Null is not an ObjectHome Link
Using the Firestore Rest API

Using the Firestore Rest API

June 25, 2021 4 min read

The documentation for working with the Firestore Rest API isn't very detailed. So here is a quick breakdown for performing the most common tasks.

Contents

  1. Create a Firestore Document
  2. Edit an existing Firestore Document
  3. Get an existing Firestore Document
  4. Data Types
  5. Firestore Rules
  6. Authentication

Create a Firestore Document

  • The Base Url for working with the Rest API is: /firestore.googleapis.com/v1/
  • Project Id: Firebase Project Id
  • (default): The documentation refers to this as the Database ID, including the brackets
  • Collection Name: The name of a Firestore collection
POST
{baseUrl}/projects/{projectId}/databases/(default)/documents/collectionName

Payload and format

{
  "fields": {
    "name": {
      "stringValue": "Peter Parker"
    },
    "age": {
      "integerValue": 17
    },
    "created": {
      "timestampValue": "2021-06-21T18:17:39.795Z"
    }
  }
}

This will create a document with an auto-generated Document Id

Edit an existing Firestore Document

Make a PATCH request to Edit an existing Document, be sure to include the documentId

PATCH
{baseUrl}/projects/{projectId}/databases/(default)/documents/collectionName/documentId

Payload and format

{
"name": "projects/{projectId}/databases/(default)/documents/collectionName/documentId"
"fields": { "name": {
"stringValue": "Clark Kent"
}, "age": {
"integerValue": 22
}, "created": { "timestampValue": "2021-06-21T18:17:39.795Z" } } }

Ensure the path to the document name is also included under the name field.

If the Document ID exists, it will edit the document with the new values. If the Document ID doesn't exist, it will create a new Document.

Get an existing Firestore Document

Make a GET request

GET
{baseUrl}/projects/{projectId}/databases/(default)/documents/collectionName/documentId

Data Types

The most common Data Types are:

  • stringValue - example usage shown above
  • integerValue - example usage shown above
  • timestampValue - example usage shown above
  • arrayValue
  • mapValue

Using arrayValue

Editing the current document to add an array of string values.

{
  "name": "projects/{projectId}/databases/(default)/documents/collectionName/documentId"
  "fields": {
    "name": {
      "stringValue": "Peter Parker"
    },
    "age": {
      "integerValue": 17
    },
    "created": {
      "timestampValue": "2021-06-21T18:17:39.795Z"
    },
"hobbies": {
"arrayValue": {
"values": [
{
"stringValue": "hanging around"
},
{
"stringValue": "surfing the web"
}
]
}
},
} }

Using arrayValue with mapValue

Editing the current document to add an array of objects

{
  "name": "projects/{projectId}/databases/(default)/documents/collectionName/documentId"
  "fields": {
    "name": {
      "stringValue": "Peter Parker"
    },
    "age": {
      "integerValue": 17
    },
    "created": {
      "timestampValue": "2021-06-21T18:17:39.795Z"
    },
"thingsToBuy": {
"arrayValue": {
"values": [
{
"mapValue": {
"fields": {
"quantity": {
"integerValue": 1
},
"item": {
"stringValue": "spider suit"
}
}
}
},
{
"mapValue": {
"fields": {
"quantity": {
"integerValue": 2
},
"item": {
"stringValue": "web shooter"
}
}
}
}
]
}
}
} }

Firestore Rules

We can make unauthenticated requests to Get, Edit and Create Firestore documents just by passing the API key as a parameter, as long as the Firestore Rules allow it.

Insecure Firestore Rules as shown below are bad practice and open to malicious activity, any user can access or change the data.

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
     match /collectionName/{document=**} {
      allow read,write: if true;
    }
  }
}

To only allow authenticated requests, we need to make the following change.

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
     match /collectionName/{document=**} {
allow read,write: if request.auth.uid != null
} } }

If we now try making any unauthenticated CRUD requests, we should see an error.

{
  "error": {
    "code": 403,
    "message": "Missing or insufficient permissions.",
    "status": "PERMISSION_DENIED"
  }
}

Authentication

Firebase allows several methods of Authentication and Authorization

The quickest and easiest way is to:

  • Sign in anonymously
  • Obtain an idToken fron the response
  • Send the idToken in the CRUD request headers.

Signing in Anonymously

POST
https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=YOURAPIKEY

Id Token in Response

{
  "kind": "identitytoolkit#SignupNewUserResponse",
"idToken": "aVeryLongString",
"refreshToken": "anotherLongString", "expiresIn": "3600", "localId": "S0x3435ETWTWEr" }

Request Headers

Authorization: Bearer {idToken}

We can now use the idToken from the response and attach it to the headers of the CRUD requests.