REST API for Google Firestore Tutorial

I have invested some time on getting this to work, so I thought it may be of help to others. Please bear with me, but it’s a work in progress.

  1. Use the Firestore API Explorer to get insights on required schemas for Composer, and DO try the API there.
  2. Set a different Resource Id for each type of call you will make to Firestore. It will be easier to try different configurations.

For now, I can:

  1. GET all documents in a collection
  2. GET one document by Id
  3. POST a new document to a collection

The basic settings for Composer REST API direct integration for an open database (no authentication):

  1. BASE TAB:
    Resource URL: https://firestore.googleapis.com/v1/
    HTTP Header: none
    URL placeholder: none
    Query parameter: none

To GET all documents in a collection, on the Composer REST API direct integration:

  1. GET (ALL) TAB
    Relative path: projects/{databaseId}/databases/(default)/documents/./{collectionId}
    Response key path: documents
    HTTP Header: none
    URL placeholder: none
    Query parameter: none

  2. Run a test, and Set Schema from Response

To GET one document in a collection, on the Composer REST API direct integration:

  1. GET (ONE) TAB
    Relative path: projects/{databaseId}/databases/(default)/documents/./{collectionId}/{id}
    Response key path: none
    HTTP Header: none
    URL placeholder: KEY: id, VALUE: {documentId}
    Query parameter: none

  2. Run a test, and Set Schema from Response

To POST (create) a new document to a collection, , on the Composer REST API direct integration:

  1. POST TAB
    Relative path: projects/{databaseId}/databases/(default)/documents/{collectionId}
    Response key path: none
    HTTP Header: none
    URL placeholder: KEY: id, VALUE: {documentId}
    Query parameter: none

  2. Set a Custom Schema exactly as the JSON generated on the Firestore API Explorer. A example follows:



    Notes:
    In Composer, as you create the custom schema, it generates an id property for each object. You have to erase it!
    Composer will order properties by ascending name.
    Your data will be on the stringValue property (ie: dirInm.codPost.stringValue)

Finally, I will be adding settings as I get them to work :sweat_smile:

2 Likes

Awesome work, and sorry we didn’t have a chance to help you debug this in more depth earlier!

Once you’re happy with this, would you be opposed to publishing it on https://docs.appgyver.com as an official tutorial (with due credit, of course)?

Sure. Once I finish to figure out the settings for the other basic calls (query by field, patch and delete) I would be pleased if you make it part of your documents.

Alright, just ping us when you’re done, we’ll review it and set it up. The format for our docs is Markdown, so if you’re comfortable writing the steps in Markdown, that will be helpful.

Sorry guys, there is an error on the POST instructions. There should be no info on the URL placeholder. It seems that on writing I pasted the values of for GET (ONE).

Thanks for posting this. I was spinning my wheels trying to get the REST API to work.

I’ve been able to get the following to work …

  1. GET all documents in a collection
  2. GET one document by id

And I’m working on …

  1. POST a new document to a collection
  2. Update an existing record
  3. Delete an existing record

Question 1: I’m stuck a trying to get POST to work and I can’t seem to match up the Custom Schema to the Firestore API Example. Do you have something with a simple example? Just a few fields so that I can match up exactly.

Question 2: How would you go about updating an existing record? Updates in Firebase seem to happen via a HTTP PATCH request.

Question 3: How would you suggest adding back security? Right now everything is wide open.

I feel I’m so close to getting this to work!

Any suggestions would be welcomed.

Woot! Just got the POST to work. The trick was to set each field as an object and setup the stringValue as a field that contains the data!

Also got the DELETE to work. You set it up just like the GET (ONE) TAB.

Still have these outstanding questions if anyone has any ideas …

For PATCH, that’s a pending feature: https://tracker.appgyver.com/feature-requests/p/rest-api-direct-integration-needs-support-for-patch-method

Currently the way to circumvent this is to use the HTTP request flow function, which you can then wrap in your own “Update in Firebase” flow function to get input/output schemas. It’s a bit inconvenient but doable.

For security, the only way to securely deliver an API key to a client app is to have a backend where the user can login with some credentials, and then the successful response returns the API key that is then stored as an app variable and possibly persisted via e.g. client-side storage. Of course preferably, this API key/authorization token is user-specific and gives just the required access.

Thanks. I’ll check-out the HTTP request flow function for the PATCH to update existing records.

To send the HTTP login details to firebase.auth (or any 3rd party auth) … would I also use the HTTP request?

Found your response to the HTTP login details in another post. Tx!

I see you got the schema right.
About security, Firestore provides OAuth2. A starting point to begin is https://firebase.google.com/docs/firestore/use-rest-api

It works pretty much like any other database. You get a key and pass it on the REST request. I suggest you do it on the base configuration tab of your appGyver Data configurator. I tried once and worked fine, but since I’m trying to figure out the REST API configuration for all usual calls, I reverted to the non secure connection in order to have less posible variables into account.

As for PATCH, I have not been able to get it to work, but still trying.

A final word on the schema: Firestore JSON is a tree of objects, with the final “branch” a stringValue/ timestampValue property with the actual data. On the REST API Data Configurator of AppGyver it looks like this:


Note the createTime, name and updateTime properties, which contain info about the document on Firestore:
createTime and updateTime are automatically filled by Firestore on PUT/POST calls, while name (which contains the document id), if absent, it’s also auto filled.
Also, as you can see in the image, the map in Firestore translate to a mapValue property on the AppGyver schema, which is also an object that contains a fields property, and so on.

Is this a bug???

I was not able to get the POST to work using Create record flow function.

I can run the POST successfully in the DATA CONFIGURATOR when I use the Test API call response. Shows success and the record is created in the DB.

When I use Create record flow function. It doesn’t return an error however the record is not created in the database. When I look at the response body it’s listing all records in the DB. Not sure why it does this?

I was able to get a POST working using the HTTP request flow function. No error returned and the response body is correct.

Will be using the HTTP request flow function as a workaround.

Hi Ron,

Can you send me an image of each, the schema and the config tab for the post request?

Ron,

Can you send me also an image of the logic flow for the page in which you make the post?

Hello @Eduardo_Jaramillo and all.
I did follow your steps and manage to get the POSTing of a new document in Firestore to work. However with this step, Firestore auto generates the document ID.
Did anyone of you manage to get the POST to work with a Custom Document ID? have tried the URL placeholder stuff without any luck.
Thanks

Firestore generates the id on as part of the name. You would have to send a name that includes the full path as in the following:

name:“projects/{yourdatabase}/databases/(default)/documents/{collectionId}/{documentId}”

You have to make sure your create record (post) custom schema includes name, as follows:
image

Hope this helps

Hello @Eduardo_Jaramillo,
That doesn’t appear to work either.
I have tried the document ID with and without the {} variable without any luck.
I did set the name to the below:

A: projects/myDataBase/databases/(default)/documents/myCollection/DocPosition5
B: projects/myDataBase/databases/(default)/documents/myCollection/{myDocID}
C: projects/myDataBase/databases/(default)/documents/myCollection/

Note: in section “B”, the value for URL placeholder for “myDocID” is set to a chosen string eg “DocPosition5”

However, if i set the name to section “C” above (ie without the Custom ID), it does work, but then the Firestore auto generates the document ID. This also confirms a working “custom schema” i guess.

For both sections “A” and “B”, i do get the below error for the name:

Error: JSON error response from server: {“error”:{“code”:400,“message”:“Document parent
name “projects/myDataBase/databases/(default)/documents/myCollection” lacks “/” at index
56.”,“status”:“INVALID_ARGUMENT”}}.status: 400

A quick reference to the Google Firestore Docs shows that the Document-ID is part of a Query
parameter. So i tried using the Query parameter in AppGyver under the POST method, again without
any success.
https://firebase.google.com/docs/firestore/reference/rest/v1/projects.databases.documents/createDocument

Did this work for you or you’re yet to test it?

Thanks

hi,

Sorry, I forgot to include somethings important on the setup of the REST API and made a mistake on the content of name (it should only be the documentID, without the path). Sorry for the inconvenience and time lost.

The set up is as follows (instead of name the images have “id”):


Note the “?documentId={id}” in the relative path. It tells Firestore the name you will give to the document ID. Set the schema from GET.


The “id” in the relative path is the first input in the Create record flow function.

Hello @Eduardo_Jaramillo,
It works like a charm. The trick as mentioned is the “?documentId={id}” in the relative path extention to the Firestore name.
Much appreciated.

Thanks.