How to get all documents after some specific document REST Firestore? - firebase

I'm investigating using Firestore in my app. Currently I try to understand is it possible to get documents that start from some specific item. I have next task: The app load all documents that currently in database. After some time the app want to download newest documents that weren't downloaded yet. I see that every document has uniq id that creates by Firestore system and I want to use it to get all document after item with specific id.
Currently I use next link
https://firestore.googleapis.com/v1beta1/projects/{myawesome_project}/databases/(default)/documents/test
and I see next result
{
"documents": [
{
"name": "projects/{myawesome_project}/databases/(default)/documents/test/MWmpU4j2tx9GwazVJZGe",
"fields": {
"f3": {
"integerValue": "3"
},
"f2": {
"stringValue": "v2"
},
"f1": {
"stringValue": "v11"
}
},
"createTime": "2018-03-07T22:51:33.578626Z",
"updateTime": "2018-03-07T23:02:18.346358Z"
},
{
"name": "projects/{myawesome_project}/databases/(default)/documents/test/TzKJzpodgolviEIVzmq0",
"fields": {
"f3": {
"integerValue": "1"
},
"f2": {
"stringValue": "v2"
},
"f1": {
"stringValue": "v1"
}
},
"createTime": "2018-03-07T22:51:07.098609Z",
"updateTime": "2018-03-07T23:02:28.964951Z"
},
{
"name": "projects/{myawesome_project}/databases/(default)/documents/test/xuGRH1NSdpiri3uYaHnl",
"fields": {
"f1": {
"stringValue": "v12"
},
"f3": {
"integerValue": "2"
},
"f2": {
"stringValue": "v22"
}
},
"createTime": "2018-03-07T22:51:53.276245Z",
"updateTime": "2018-03-07T23:01:57.788212Z"
}
]
}
Let's say the app downloaded everything by document TzKJzpodgolviEIVzmq0(second one), and in next request I want to get all data from this point. I tried use orderBy=name, but it doesn't work
https://firestore.googleapis.com/v1beta1/projects/{myawesome_project}/databases/(default)/documents/test?orderBy=name&startAt=TzKJzpodgolviEIVzmq0
Does anyone know how to get documents from some specific document

Related

BatchWrite REST API JSON Structure for FireStore

I know how to compose JSON when you want to create a single document on FireStore.
# Query String
"updateMask.fieldPaths": [
"`price`",
"`status`"
]
# Body
"fields": {
"price": {
"stringValue": "165.00"
},
"status": {
"stringValue": "active"
}
}
But when it comes to BatchWrite I cannot understand what the doc implies
https://cloud.google.com/firestore/docs/reference/rest/v1/projects.databases.documents/batchWrite
Currently I'm doing this with Python library I deployed on cloud computing resource(pipedream) but I want to do this within Make.com and its "Make API Call" module so I need to know the curl style or REST JSON syntax.
I'm assuming fields go to "writes" but not sure what goes to "labels" object.
Exactly what's the write structure for this call?
{
"writes": [
{
"update": {
"name": "projects/project_id/databases/(default)/documents/service_order/352003090342435.5f357270173e8c70878.-9486573",
"fields": {
"managed_by": {
"booleanValue": "false"
},
"location2": {
"booleanValue": "false"
},
"made_by": {
"stringValue": "352003090342435.5eda4f3c17284c58460.90921842"
},
"phone2": {
"stringValue": "0665439307"
},
"state": {
"stringValue": "confirm"
},
"write_date": {
"stringValue": "1597664391000"
},
"made_by_name": {
"stringValue": "FaridBenabdallah"
},
"description": {
"stringValue": "e1"
},
"accepted_offer": {
"booleanValue": "false"
},
"id": {
"stringValue": "352003090342435.5f357270173e8c70878.-9486573"
},
"location1": {
"stringValue": "352003090342435.5f3572a0173e8c7c336.-8281409"
},
"date_order": {
"booleanValue": "false"
},
"order_type": {
"stringValue": "Minuiserie"
},
"phone1": {
"stringValue": "0657331995"
}
}
},
"updateMask": {
"fieldPaths": [
"managed_by",
"location2",
"made_by",
"phone2",
"state",
"write_date",
"made_by_name",
"description",
"accepted_offer",
"id",
"location1",
"date_order",
"order_type",
"phone1"
]
}
}
]
}
This another stackoverflow article helped me
If there is null you need to change the intended value type to nullValue.

Firestore Pagination: how to define **unique** 'startAt'-cursor for REST?

This is a follow up question to an already solved one.
For this previous question an answer was given, how to define a cursor for query-pagination with 'startAt' for REST, that relates to a range of documents. In the example below, the cursor relates to all documents with an 'instructionNumber.stringValue' equal to "instr. 101". According to my testing, this results in skipping of documents.
New question:
How has the cursor to be defined, to not only relate to the stringValue of a field, that the query is ordered by? But instead to a distinct document (usually defined by its document-id)?
"structuredQuery": {
"from": [{"collectionId": "instructions"}],
"where": {
"fieldFilter": {
"field": {
"fieldPath": "belongsToDepartementID"
},
"op": "EQUAL",
"value": {
"stringValue": "toplevel-document-id"
}
}
},
"orderBy": [
{
"field": {
"fieldPath": "instructionNumber"
},
"direction": "ASCENDING"
}
],
"startAt": {
"values": [{
"stringValue": "instr. 101"
}]
},
"limit": 5
}
}
For better understanding, here is the condensed schema of the documents.
{
"document": {
"name": "projects/PROJECT_NAME/databases/(default)/documents/organizations/testManyInstructions/instructions/i104",
"fields":
"belongsToDepartementID": {
"stringValue": "toplevel-document-id"
},
"instructionNumber": {
"stringValue": "instr. 104"
},
"instructionTitle": {
"stringValue": "dummy Title104"
},
"instructionCurrentRevision": {
"stringValue": "A"
}
},
"createTime": "2022-02-18T13:55:47.300271Z",
"updateTime": "2022-02-18T13:55:47.300271Z"
}
}
For a query with no ordering:
"orderBy": [{
"direction": "ASCENDING",
"field": {"fieldPath": "__name__"}
}],
"startAt": {
"before": false,
"values": [{"referenceValue": "last/doc/ref"}]
}
For a query with ordering:
"orderBy": [
{
"direction": "DESCENDING",
"field": {"fieldPath": "instructionNumber"}
},
{
"direction": "DESCENDING",
"field": {"fieldPath": "__name__"}
}
],
"startAt":
{
"before": false,
"values": [
{"stringValue": "instr. 101"},
{"referenceValue": "last/doc/ref"}
]
}
Be sure to use the same direction for __name__ as the previous "orderBy" or it will need a composite index.
To ensure you have identify unique document for starting at you'll always want to include the document ID in your call to startAt.
I'm not sure of the exact syntax for the REST API, but the Firebase SDKs automatically pass this document ID when you call startAt with a DocumentSnapshot.

Query Firebase using Rest Call

I am querying firestore using query
https://firestore.googleapis.com/v1/projects/myproject/databases/(default)/documents/mycollection
I am getting following Json. Can someone please help me how can I filter my query based on Rate field. I am writing following query and it doesn't work
https://firestore.googleapis.com/v1/projects/myproject/databases/(default)/documents/mycolletion?Rate="15"
{
"documents": [
{
"name": "0C45nDuozgQDOwEx5xHR",
"fields": {
"Clinic": {
"stringValue": "American Hospital"
},
"Rate": {
"stringValue": "140"
},
,`enter code here`
"createTime": "2020-06-28T20:32:18.776123Z",
"updateTime": "2020-07-22T21:19:24.061647Z"
},
{
"name": "Jm3tNVWmk4Q1pk87KL1m",
"fields": {
"Clinic": {
"stringValue": "Cleaveland clinic"
},
"Rate": {
"stringValue": "150"
},
"createTime": "2020-06-28T20:28:03.726819Z",
"updateTime": "2020-07-22T21:19:05.073019Z"
}
}
The problem is that the Rate field is an object (inside another object to make it worse), so in order to achieve that you would either need to update you Firestore structure to do it all in the request URL, or you would have to use a structured query in the body of the request.
Change the structure:
In order to work with the request you already have, you will need to change the structure to (using the 1st document as an example):
{
"name": "0C45nDuozgQDOwEx5xHR",
"Clinic": "American Hospital",
"Rate": "140",
"createTime": "2020-06-28T20:32:18.776123Z",
"updateTime": "2020-07-22T21:19:24.061647Z"
}
which in my opinion makes it simpler although I don't have the full picture
Have a Structured query in your request body:
To keep the structure you already have you will need to use thisURL:
https://firestore.googleapis.com/v1/projects/myproject/databases/(default)/documents/:runQuery
And add this to the body of the request:
"structuredQuery": {
"from": [{
"collectionId": "mycollection"
}],
"where": {
"fieldFilter": {
"fields": {
"Rate": {
"stringValue": "15"
}
}
}
}
}
You can check more details by checking the runQuery Documentation and the structuredQuery Documentation for what else you can do with these options.

How To Get Data Ordered From Firebase REST API

I have a Firebase database of players scores .
Ex .
{
"documents": [
{
"name": "2SjkDBRLpNNUrWQzkKZxGaaaEIT2",
"fields": {
"PlayerName": {
"stringValue": "Player1"
},
"score": {
"integerValue": "51"
}
},
"createTime": "2020-04-08T16:57:22.016282Z",
"updateTime": "2020-04-08T16:57:22.016282Z"
},
{
"name": "OkLV0Od4UBQbJVADOJkCM0l2ayM2",
"fields": {
"score": {
"integerValue": "119"
},
"PlayerName": {
"stringValue": "Player2"
}
},
"createTime": "2020-04-08T16:03:06.417921Z",
"updateTime": "2020-04-08T16:03:06.417921Z"
}]
}
i am using the REST API to get this data in my game (Godot Engine), by sending an http request to
https://firestore.googleapis.com/v1/projects/{ProjectId}/databases/(default)/documents/scores
When sending the request the response i get is only random 20 documents .
MY QUESTION IS :
How can i get the First 20 Players (documents) ordered by the "score" "IntegerValue" even if the data is more than 1000 documents.
Thank you .
DatabaseReference ref = FirebaseDatabase.getInstance.getReference("<your_main_node>");
Query query = ref.child("documents").child("score").orderByChild("integerValue").limit(20);

Send a list of objects whose information is obtained by asynchronous functions

I hope I can express myself a way you can all understand.
Here's the thing, I'm developing a back-end for an app in nodeJS. There's a table named 'chat' in dynamoDB with the ID of the chat's creator and a list of messages IDs, also there's a table named 'messages' with the author of each message and the text.
When the front-end asks the server for all the chats it has to send a list of chats objects with this sctructure:
[
{
"ID_CHAT": {
"S": "asd123asd"
},
"author": {
"name": "Name",
"lastname": "Lastname"
},
"date": {
"S": "19/11/2017 16:00"
},
"USER_DESTINATION": {
"S": "222asd222"
},
"messages": [
{
"Item": {
"author": {
"name": "Name",
"lastname": "Lastname"
},
"text": {
"S": "Hi!"
},
"MESSAGE_ID": {
"S": "456asd456"
},
"date": {
"S": "19/11/2017 16:05"
}
}
},
{
"Item": {
"author": {
"name": "Name",
"lastname": "Lastname"
},
"text": {
"S": "zup?"
},
"MESSAGE_ID": {
"S": "789asd789"
},
"date": {
"S": "19/11/2017 16:06"
}
}
}
]
}
{
"ID_CHAT": {
"S": "123asd123asd"
},
"author": {
"S": "123asd123"
}, and so on...
]
But in order to send this I need to get the chat's authors data from dynamodb (asynchronous function) and the list of messages data again from dynamodb.
I tried combining map() to get the chats authors and Promise.all() for the messages but it won't work cause the second iteration of the map() function runs after the Promise.then().
I'll appretiate your help!

Resources