I have a query that is not working as I expect it to. I have a collection called 'games' that has a number of documents in it.
Each document has an array called 'hiScores' that consists of the results from that round. I would like to query all games for a specific player for example:
.where('hiScores.playerName', '==', 'David Lamm')
This is not returning anything. I have no problems when querying a top level variable in the document. What have I done wrong?
Database:
db.collection('games')
.where('hiScores.playerName', '==', 'David Lamm')
.get()
.then(function(querySnapshot) {
console.log('Davids games:')
querySnapshot.forEach(function(doc) {
console.log(doc.id, " => ", doc.data());
});
})
.catch(function(error) {
console.log("Error getting documents: ", error);
}
);
The problem is that the hiScores field is an array, not an object. You can tell it's an array because the first immediate element of the array in the screenshot has index 0. You're trying to query hiScores as if it's a single object with a single property called playerName.
Firestore doesn't support querying for object properties within within array fields. If you have an array field, you can only query to find documents where an entire item is present in the array (an arrayContains query).
As pointed out by Doug this is currently not possible in firestore.
You can create a top level array of strings in each game named playerNames[]. Then use the where condition on playerNames with array_contains.
Related
I don't think I'm very far from the answer, I tried to query an id inside an array on Firestore.
I wanna compare the id of the participants.
Also my DB in Firestore:
And also my function, for the moment my function return size =0 so they can't catch the query.
const deleteAbuse = (type) => {
const participants = channel?.otherParticipants;
if (!participants || participants.length != 1) {
return;
}
const myID = currentUser.id;
const otherUserID = participants[0].id;
console.log('id user', otherUserID);
channelDB
.where('participants.id', '==', otherUserID)
.get()
.then((querySnapshot) => {
console.log(querySnapshot.size);
querySnapshot.forEach((doc) => {
console.log(doc.ref);
//doc.ref.delete();
});
});
};
There is no way you can query filter your "channels" collection to get documents based only on a single field of an object that exists inside the participants array. In other words, you cannot create that filtering based only on that ID. To be able to filter the data, you should pass to the where() function, the entire object, and not only some partial data. The object should contain values for all the fields. Only the ID is not enough.
And also my function, for the moment my function return size =0
That's the expected behavior since in your array there isn't any object that holds only a single field called id. All objects hold 7 fields, or even more than that, as I cannot see all fields in your screenshot.
I wrote an article called:
How to update an array of objects in Firestore?
Where you can find in the first part, the simplest way to get a custom object from an array of custom objects.
Alternatively, you can create an array that can hold only the IDs of the participants, filter the documents and create another database call to get their corresponding data.
This question already has answers here:
Wildcard Firebase Query [duplicate]
(1 answer)
Google Firestore: Query on substring of a property value (text search)
(25 answers)
Closed 1 year ago.
let info = "every doc that starts with input preferable where i can place a limit on"
firebase.firestore().collection("usernames").doc(info);
I want to make a search bar where I get all users depending on the value I type in.
And I'm not sure how to do that exectly. basicaly I want to get all docs in the collection usernames that contain some input string
To start with, what you have done with the code above is create a document with an id of the string 'info'. Only one unique id could exist which would make querying unnecessary. In order to do a string search it would also be best to split the string into an array. II assume what you want to do is something like:
let info = "some string to go in document"
info = info.split(" ");
// Add a new document with a generated id.
firebase.firestore().collection("usernames").add({
info: info
})
.catch((error) => {
console.error("Error adding document: ", error);
});
Then you can query all documents in the collection to see if the info array contains a certain string word:
let check = "string"
firebase.firestore().collection("usernames").where('info', 'array-contains', check).get().then(function(querySnapshot) {
querySnapshot.forEach(function(doc) {
console.log(doc.id, " => ", doc.data());
});
});
Hope this is helpful, its a difficult problem
I am saving data in a Document like the below image. I want to fetch the records from array notifyArray , ctg where array-contains Burger.
This is the code i am trying :
firebase.firestore().collection(`notifications`)
.where("notifyArray", "array-contains", 'Burger')
.onSnapshot(querySnapshot=> {
querySnapshot.forEach(doc=> {
console.log(doc.data());
console.log("Search result");
var data = Object.assign(doc.data(), {docid : doc.id})
this.goalList1.push(data);
});
console.log(this.goalList1);
});
But it is not returning any result. Ideally it should return 2 records.
The array notifyArray is an array of maps, each map containing two properties. Firestore doesn't support querying of map properties in an array. You can only search for the entire contents of the map, which means you have to know all of the values of all of its fields.
What you can do instead is make a new array that contains only the string values of the food property in the map, then query that array instead.
firebase.firestore()
.collection(`notifications`)
.where("foodArray", "array-contains", 'Burger')
Above, the query is expecting that there is an array of strings called foodArray.
This question already has an answer here:
Firestore array-contains-any is not working properly
(1 answer)
Closed 3 years ago.
Hello i'm implementing the array-contain query but everytime i'm trying i'm Getting blank snapshot. My code is:
getStation = () => {
const query = firebase
.firestore()
.collection('routes')
.where('station', 'array-contains', 'station_name ');
query.get().then(snapshot => {
console.log("snapshot", snapshot);
snapshot.docs.forEach(doc => {
alert("eri")
console.log("eryh", doc.data);
})
})
.catch(err => {
console.log('Error getting documents', err);
});
}
I even tried to pass the static values but not able to get the desire value.
In your code there is a problem with typo mistake station must be stations
.where('station', 'array-contains', 'station_name ');
must be
.where('stations', 'array-contains', 'station_name ');
I hope it will fix your problem.
Update Answer
There is also typo mistake in station_name you just added the space after station_name
.where('station', 'array-contains', 'station_name ');
must be
.where('stations', 'array-contains', 'station_name');
You are trying to use array-contains to check for a field inside a map. This is not supported.
The array-contains can only search for a field inside the array and not a field inside a map which is inside that array.
A workaround I have tested is that you add an extra field inside the array that will be a boolean or a string and you can query based on it.
Using a boolean field in the array:
.where('stations', 'array-contains', true);
Using a String field in the array:
.where('stations', 'array-contains', 'station_name exists');
The array-contains operation checks if the precise object/value you specify exists in the array. It can't check on subsets of the array elements, only on complete values. So in your current structure, you'd have to pass all properties into the array-contains call:
.where('station', 'array-contains',
{ station_address_name: '...', station_lat_long: ..., status_name: '...' });
This typically is not feasible, in which case you'll want to store the elements that you want to filter on in a (additional) separate field in your documents. In this example, since you want to filter on station names, you'd add a field station_names where you store just the station names. Then you can query with:
.where('station_names', 'array-contains', 'name to search for')
Also see:
Firestore to query by an array's field value
Firestore array-contains-any is not working properly
How to make query spot only the some value in a Map inside an Array in flutter (dart)?
My firestore database currently looks like this:
firestore db
how can I get the value of, say, DEVICES/ID.
currently my code returns undefined when i try to get the value.
var userDeviceRef = db.collection("USERS").doc(data.uid);
userDeviceRef.get().then(function(doc){
if (doc.exists) {
console.log("Document data:", doc.data());
console.log("document customdata foo: " + doc.data().DEVICES.ID);
}
}
data.uid returns a proper value. the value of the document ID.
doc.data() returns all the fields and its children in what appears to be string format. however when I add DEVICES.ID, it returns undefined. how can i get the nested data as shown in the image?
Your field called DEVICES is actually an array. As far as I can tell, it has at least one element in it. If you want the value of the ID field of the first element of that array, you'll have to index into that array:
doc.data().DEVICES[0].ID