Firestore - Index a field that contains a map with unknown keys - firebase

Im trying to run this query in a Flutter application.
the field Archived is a map with two key value pairs. The keys are the IDs of the users.
.collection('games').orderBy("finished")
.where("players", arrayContains: FirebaseAuth.instance.currentUser!.uid)
.where("archived.${FirebaseAuth.instance.currentUser!.uid}",
isEqualTo: false)
.snapshots();
The code works great without the "orderBy" , with indexes:
{
"collectionGroup": "games",
"queryScope": "COLLECTION",
"fields": [
{ "fieldPath": "players", "order": "ASCENDING" },
{ "fieldPath": "archived", "order": "ASCENDING" },
]
}
The problem is that when i add finished to the index..it does not help.
I get an error with a link to create the index..but that only creates the index, with archived.playerId.
Any tips?

Related

Firestore structured query search by document id

I'm trying to query a firestore collection by document id but not using firestore CLI but rather a structured query (because I'm using Zapier to automate some workflows). Is there a way to search by documented as the field? So far I've tried the below code and variations where I replace name with "documentId()", "documentId" and nothing seems to work. When I use name I get the following error:
"error":
"code": 400,
"message": "key filter value must be a Key",
"status": "INVALID_ARGUMENT"
"where": {
"fieldFilter": {
"field": {
"fieldPath": "__name__"
},
"op": "EQUAL",
"value": {
"stringValue": "THE ID I WANT TO LOOK FOR"
}
}
}
If you want to get a document by id using __name__, change the value type to referenceValue and provide the full path to the document instead of just the id for the query.
"where": {
"fieldFilter": {
"field": {
"fieldPath": "__name__"
},
"op": "EQUAL",
"value": {
"referenceValue": "projects/project_id/databases/database_id/documents/your_collection/doc_id"
}
}
}
Assuming that you want to get a specific document using a document id. You may want to refer to the code below:
axios.get(`https://firestore.googleapis.com/v1/projects/<Project-ID>/databases/(default)/documents/<Collection-Name>/<Document-ID>`)
.then(res => {
console.log(res);
})
.catch(error => {
console.log(error);
});
The code above will get a specific document that you want. If you want to get a document ID with a specific value of its field, then this line here: "fieldPath": "__name__" should be a fieldName not a document id. "fieldPath": "<FieldName>". and also, make sure the method you're using is POST. See code sample below for reference:
axios.post(`https://firestore.googleapis.com/v1/projects/<Project-ID>/databases/(default)/documents:runQuery`,
{
"structuredQuery": {
"from": [{
"collectionId": "<Collection-Name>"
}],
"where": {
"fieldFilter": {
"field": {
"fieldPath": "<FieldName>"
},
"op": "EQUAL",
"value": {
stringValue: "<FieldValue>"
}
}
}
}
}).then(res => {
console.log(res)
})
.catch(error => {
console.log(error)
})
All the codes above are for reference only which I used axios for fetching the data from Firestore.
For more information, checkout this documentation.

How to retrieve firebase documents missing a field using runQuery and the IN operator?

This is my http POST requst body...
{
"structuredQuery": {
"select": {
"fields": [
{
"fieldPath": "name"
},
{
"fieldPath": "taxId"
},
{
"fieldPath": "mailingAddress"
}
]
},
"from": [
{
"collectionId": "orgs"
}
],
"where": {
"fieldFilter": {
"field": {
"fieldPath": "orgId"
},
"op": "IN",
"value": {
"arrayValue": {
"values": [
{
"stringValue": ""
},
{
"nullValue": null
}
]
}
}
}
}
}
It fails to return orgs where the orgId field is completely missing from the document. It correctly includes orgs where the orgId field is present and equal to empty string. This is accessing a Cloud Firestore db.
Due to the way Firestore indexes data, it is not possible to query for documents for which a certain field "is completely missing from the document": the field needs to exist in order for the Firestore index to take it into account. More details on the indexing mechanism in the following official video.
You may store an empty value in this field, as you mention in your question.

Possible bug with new ga:clientId GA API field

I'm trying out a new default clientID dimension in Google Analytic Reporting API.
I keep getting duplicate clientIDs and total event action count for the same day when the RowCount is > 10000. I can easily get rid of unwatned rows but I wonder why it happens.
I retrieve data for one day and filter on Event Action. I get the sampled data.
What's more the count of total events retrieved by Reporting API is larger than the one retrived by User Activity API for the same clientID. The former is sampled while the latter is not so the count should actually be bigger in the second case.
My queries look like this:
Reporting API
query = {
'reportRequests': [
{
'viewId': '',
'dateRanges': [{'startDate':'2019-08-21', 'endDate': '2019-08-21'}],
'metrics': [
{'expression': 'ga:totalEvents'} ],
'dimensions': [{'name':'ga:clientID'}],
'dimensionFilterClauses': [
{ 'operator': 'OR',
'filters': [
{
'dimensionName': 'ga:eventAction',
'not': False,
'expressions':[
''
],
'caseSensitive': False
},
],
}
],
'segments': [],
'samplingLevel':'LARGE',
'pageSize':'10000',
}
]
}
User API
queryUser = {
"viewId": "",
"user": {
"type": "CLIENT_ID",
"userId": ""
},
"dateRange": {
"startDate": "2019-08-21",
"endDate": "2019-08-21",
}
}
It's still an undocumented feature so maybe that's why I'm getting these errors. Or could there be more fixable reasons?

What is the JSON format for a firestore individual field index within a collection group query?

We can now retrieve documents from a collection group which is great. To do so, I need to create an index through an error message on the Firebase console. How can I add this new index to the firestore.indexes.json file?
Example of the documentation:
let museums = db.collectionGroup('landmarks').where('type', '==', 'museum');
museums.get().then(function(querySnapshot) {
querySnapshot.forEach(function(doc) {
console.log(doc.id, ' => ', doc.data());
});
});
At the top level of your index file, add a new element called fieldOverrides and populate it like this:
{
"fieldOverrides": [
{
"collectionGroup": "landmarks",
"fieldPath": "type",
"indexes": [
{
"order": "ASCENDING",
"queryScope": "COLLECTION"
},
{
"order": "DESCENDING",
"queryScope": "COLLECTION"
},
{
"arrayConfig": "CONTAINS",
"queryScope": "COLLECTION"
},
{
"order": "ASCENDING",
"queryScope": "COLLECTION_GROUP"
}
]
}
]
}
This preserves the all the default automatic indexing for the type field in landmarks at the COLLECTION scope, and allows for type also to be used at the COLLECTION_GROUP scope.

What is the JSON format for a firestore composite index including an array?

I want to filter a collection (let's call it documents) using array-contains on one column (say keywords) and sort by another column (say name).
I am able to create this composite index in the firebase console, but I can only guess at the format for adding it to firestore.indexes.json.
It's unfortunate we can't download the index file from the console.
Set the mode to ARRAY_CONTAINS:
{
"collectionId": "documents",
"fields": [
{
"fieldPath": "keywords",
"mode": "ARRAY_CONTAINS"
},
{
"fieldPath": "name",
"mode": "ASCENDING"
}
]
}
You can also list your current Cloud Firestore indexes in JSON from the Firebase CLi:
firebase firestore:indexes
To export firestore indexes
firebase firestore:indexes > firestore.indexes.json
Caution! This will replace everything in firestore.indexes.json.
Or if you have multiple firebase projects in your .firebaserc:
"projects": {
"production": "prod-v6909",
"staging": "prod-c6020"
}
Then you can export like this:
firebase --project staging firestore:indexes > firestore.indexes.json
You can also list your current Cloud Firestore indexes in JSON from
the Firebase CLi: firebase firestore:indexes
For me this when exporting collection group indexes this is exporting a bad formatter json. The command line forget to close the array notifier on indexes:
{
"indexes": [],
"fieldOverrides": [
{
"collectionGroup": "restaurants_users_config",
"fieldPath": "user",
"indexes": [
{
"order": "ASCENDING",
"queryScope": "COLLECTION"
},
{
"order": "DESCENDING",
"queryScope": "COLLECTION"
},
{
"arrayConfig": "CONTAINS",
"queryScope": "COLLECTION"
},
{
"order": "ASCENDING",
"queryScope": "COLLECTION_GROUP"
}
}
]
}
Any Suggestions? It is right to only fix the json array by hand?
**edit
Fix: it was fixed with firebase upgrade 8.2.0 → 8.4.1

Resources