ChatMaxima Docs
Studio

Firebase Block - Firestore and Cloud Messaging in Your Chatbot

Connect Firebase Firestore and Cloud Messaging to your ChatMaxima chatbot. Read documents, query collections, and send push notifications from Studio flows.

Overview

The Firebase Block connects your ChatMaxima chatbot directly to a Firebase project. It lets your flow read and write documents in Cloud Firestore and send FCM push notifications to your mobile or web app users, all from a single block. Any operation you configure runs at the exact point in the conversation where you drop the block, so your bot can pull data from Firestore, store state back into it, or trigger a push notification in response to a specific conversation state.

Typical use cases include storing lead data in your own Firestore collections, looking up an authenticated user's profile by ID, checking order or booking status from your app's backend, and pushing notifications to a user's devices when the conversation reaches a milestone (order confirmed, appointment booked, support ticket resolved). The block handles authentication, token caching, and error routing automatically, so you only need to pick an operation and fill in the fields that matter for it.

Prerequisites

Before you add the Firebase block to a flow, make sure you have:

  • A Firebase project with Cloud Firestore enabled. Realtime Database is not supported in this block (v1 covers Firestore only).
  • A service account JSON key downloaded from your Firebase project. In the Firebase Console go to Project Settings, open the Service Accounts tab, and click Generate new private key. Save the downloaded JSON file. You will paste its contents into ChatMaxima in the next step.
  • FCM set up on your client app if you plan to send push notifications. Each device should be registered with Firebase and its FCM registration token stored in a place the bot can fetch (typically a Firestore users/{user_id}.tokens array).

Note: The service account key is a long-lived secret. Treat it the same way you treat a production database password. Do not commit it to source control or share it in chat.

Step 1: Connect Firebase as an Integration

  1. Go to DashboardIntegrations and click Add Integration
  2. Select Firebase from the platform dropdown
  3. Enter a name (for example, Production Firebase or My App Firestore) so you can recognise it later
  4. Paste the full contents of the service account JSON file into the Service Account JSON field
  5. Click Verify & Save

ChatMaxima validates the credential by signing a JWT with the private key, exchanging it for an OAuth access token, and making a test call to Firestore's listCollectionIds endpoint. If the project has Firestore enabled and the service account has access, you will see Firebase integration connected. The integration is now available to every bot on your team.

Note: The access token is cached inside ChatMaxima and refreshed automatically before it expires. You do not need to rotate or re-enter the service account JSON unless you want to move to a different Firebase project.

Step 2: Add the Firebase Block to a Flow

  1. Open your chatbot in Studio
  2. Right-click the canvas (or drag from the left sidebar) and pick Firebase under External Integrations
  3. Double-click the block to open its configuration
  4. Select the integration you created in Step 1 from the Select Integration dropdown
  5. Pick an operation and fill in the fields described below

Available Operations

The Firebase block supports seven operations. The first six work with Cloud Firestore. The seventh sends a Cloud Messaging (FCM) push notification.

OperationCategoryWhat It Does
Get DocumentFirestoreReads a single document by collection and document ID
Add DocumentFirestoreCreates a new document. Firestore generates the ID automatically if you leave it blank
Set DocumentFirestoreOverwrites the document at a specific ID. Replaces all fields
Update DocumentFirestoreMerges only the fields you provide into an existing document
Delete DocumentFirestoreRemoves a document at a specific ID
Query CollectionFirestoreFilters, orders, and limits a collection of documents
Send NotificationCloud MessagingPushes a notification to one device, many devices, or a topic

Every input (collection, document ID, field values, FCM token, notification title, and body) supports ChatMaxima variables with the {variable} syntax, so you can populate them from previous question blocks, earlier API calls, or data received in a Webhook block.

Operation Configuration

Get Document

Reads one document by ID. Use this to look up a user's profile, fetch the current state of an order, or pull any record you already have the ID for.

FieldDescription
CollectionFirestore collection name (for example, users, orders). Pick from the detected list or type a new one
Document IDThe ID to read. Supports variables like {user_id}
Store the response in variableName of the ChatMaxima variable that holds the result

Add Document

Creates a new document in a collection. Leave Document ID blank to let Firestore auto-generate one, or provide your own (for example, {lead_id}).

FieldDescription
CollectionTarget collection
Document ID (optional)Leave blank for auto ID, or provide a custom one
Field MappingKey/value rows. Keys are Firestore field names, values can be literals or {variable} references
Store the response in variableThe saved document (with its generated ID) is stored here

Set Document

Overwrites the document at collection/document_id with exactly the fields you list. Any fields previously on the document but not in your mapping are removed. Use this when you want a clean replace rather than a merge.

Update Document

Merges only the fields you provide into an existing document. Fields not in your mapping are left untouched. This is the safest write operation for incrementally updating a user's profile or order record.

Delete Document

Removes the document at collection/document_id. The response variable will contain {"success": true} if the delete succeeded.

Query Collection

Runs a Firestore structured query against a collection. Supports filters, ordering, and a row limit.

FieldDescription
CollectionCollection to query
Query FiltersRows of field, operator, value. Combined with AND
Order By FieldOptional field name to sort by
Order DirectionAscending or Descending
LimitMaximum number of documents to return. Leave blank for no limit

Supported filter operators:

OperatorMeaning
EQUALField equals value
NOT_EQUALField does not equal value
LESS_THANField is less than value
LESS_THAN_OR_EQUALField is less than or equal to value
GREATER_THANField is greater than value
GREATER_THAN_OR_EQUALField is greater than or equal to value
ARRAY_CONTAINSField is an array that contains value
INField value is one of the listed values
ARRAY_CONTAINS_ANYField array contains any of the listed values
NOT_INField value is none of the listed values

Send Notification

Sends an FCM push notification. Choose one of three targets:

Send ToWhen to Use
A Single DeviceOne specific FCM registration token
Multiple DevicesMulticast to many tokens in one step. Accepts a variable that resolves to a JSON array, a comma-separated string, or a native array
A TopicBroadcast to every device subscribed to a topic (for example, premium-users)

Configuration fields:

FieldDescription
FCM Token / Tokens / TopicThe recipient, depending on target type. Variables supported
Notification TitleBold headline shown in the push notification
Notification BodyMessage text shown below the title
Data PayloadOptional key/value pairs delivered silently alongside the notification. Useful for deep linking (for example, screen=orders, order_id={order_id}). Values are stringified before sending, per FCM rules

Response Variable Format

Every operation stores a JSON result in the variable you name under Store the response in variable. Downstream blocks can reference fields using dot notation, for example {user_data.data.email}.

Firestore reads (Get Document)

{
  "id": "user_42",
  "name": "projects/my-project/databases/(default)/documents/users/user_42",
  "data": {
    "name": "Priya",
    "email": "priya@example.com",
    "tokens": ["iphone_tok", "ipad_tok"]
  },
  "create_time": "2026-04-20T10:30:00Z",
  "update_time": "2026-04-21T14:15:00Z"
}

Firestore writes (Add / Set / Update)

The same shape as Get Document. The id field reflects the final document ID (auto-generated if you did not supply one).

Firestore Delete

{ "success": true }

Query Collection

An array of document objects, each with the shape above:

[
  { "id": "order_1", "data": { "status": "confirmed", "amount": 900 }, "create_time": "..." },
  { "id": "order_2", "data": { "status": "confirmed", "amount": 1200 }, "create_time": "..." }
]

Send Notification (single / topic)

{
  "success": true,
  "message_name": "projects/my-project/messages/0:17045...",
  "target_type": "token",
  "target_value": "iphone_tok"
}

Send Notification (multicast)

{
  "success": true,
  "sent": 2,
  "failed": 1,
  "invalid_tokens": ["stale_tok"],
  "results": [
    { "token": "iphone_tok", "success": true, "message_name": "..." },
    { "token": "ipad_tok",   "success": true, "message_name": "..." },
    { "token": "stale_tok",  "success": false, "error": "Requested entity was not found.", "error_code": "UNREGISTERED" }
  ]
}

The invalid_tokens array lists tokens that Firebase flagged as stale (UNREGISTERED, INVALID_ARGUMENT, NOT_FOUND). Use a follow-up Firebase block with Update Document to prune these from your own Firestore users collection so you stop targeting dead devices.

Common Use Cases

Order Confirmation Push Notification

A customer completes checkout in-app, and you want the bot to push a confirmation to every device the user has registered.

  1. Question Block: Capture or verify {user_id}
  2. Firebase Block (Get Document): Collection users, Document ID {user_id}, store result in {user_data}
  3. Condition Block: Branch on {order_status} == "confirmed"
  4. Firebase Block (Send Notification, Multiple Devices): Tokens {user_data.data.tokens}, title Order confirmed, body Hi {user_data.data.name}, your order {order_id} is on its way
  5. Message Block: We have sent a confirmation to your devices

Write Chatbot Leads to Firestore

Use Firestore as the source of truth for inbound leads so your own mobile app can react in real time.

  1. Question Block: Ask for {name}, {email}, {phone}
  2. Firebase Block (Add Document): Collection chatbot_leads, fields name={name}, email={email}, phone={phone}, source=chatbot
  3. Message Block: Thanks {name}, we will be in touch shortly

Check Booking Availability

Before confirming a booking, query Firestore to make sure the slot is still open.

  1. Firebase Block (Query Collection): Collection bookings, filter slot_id EQUAL {slot_id} and status NOT_EQUAL cancelled, limit 1, store in {existing_bookings}
  2. Condition Block: Branch on whether {existing_bookings} is empty
  3. On empty: Firebase Block (Add Document) to create the booking, then Message Block to confirm
  4. On match: Message Block That slot was just taken, please pick another

Broadcast to a Topic

Send a one-to-many announcement to every device subscribed to a topic.

  1. Trigger Block: Admin triggers the flow with a Campaign
  2. Firebase Block (Send Notification, Topic): Topic premium-users, title New feature released, body Tap to try it out, data screen=whats_new

Clean Up Stale FCM Tokens

After a multicast send, remove dead tokens from the user's profile so future pushes only go to live devices.

  1. Firebase Block (Send Notification, Multiple Devices): Store result in {push_result}
  2. Condition Block: Branch on whether {push_result.invalid_tokens} is non-empty
  3. Code Block or API Block: Compute the pruned token list
  4. Firebase Block (Update Document): Collection users, Document ID {user_id}, field tokens={pruned_tokens}

Best Practices

  • Scope the service account properly. Create a dedicated service account for ChatMaxima and give it only the Firestore and FCM roles it needs. Do not use the default Admin SDK key for production
  • Store FCM tokens as an array. Users often have multiple devices. Keeping them in a single tokens field per user makes multicast sends trivial
  • Handle the error branch. Every Firebase block has a second output that fires when the operation fails. Route it to a recovery message or a retry, rather than letting the flow stall
  • Prune stale tokens. FCM returns UNREGISTERED when a token is dead. Use the invalid_tokens field in the multicast response to clean up your user profiles
  • Keep data payload values small. FCM requires all data payload values to be strings and the total message size to stay under 4 KB. ChatMaxima stringifies values automatically, but large JSON blobs will be rejected by Firebase
  • Do not leak the service account JSON. Once saved in ChatMaxima, the JSON is not exposed back in the UI. Treat the downloaded file with the same care as any other production secret

Frequently Asked Questions

Which Firebase products does the block support?

Cloud Firestore (read / write / query) and Cloud Messaging (FCM HTTP v1 API). Realtime Database, Firebase Authentication, Cloud Functions, and In-App Messaging are not handled by this block.

Can I use the same block for both Firestore and FCM?

Yes. A single Firebase integration credential authorises both products. Drop separate Firebase blocks for each operation you need (for example, one Get Document block to look up the user's tokens, then one Send Notification block to push to those tokens).

Where is my service account JSON stored?

Inside the chatbot_integration_tokens table, scoped to your team. The JSON is never returned to the browser after saving. ChatMaxima uses it server-side to generate short-lived OAuth access tokens for Firebase.

Why does the notification arrive but the data payload is missing?

FCM requires data payload values to be strings. If you pass a numeric or boolean variable directly, ChatMaxima stringifies it for you, but some client apps expect specific formats. Double-check how your app reads RemoteMessage.getData() on Android or userInfo on iOS.

My multicast send shows some tokens failed. What do I do?

Look at the invalid_tokens array in the response variable. These are tokens Firebase considers dead. Use an Update Document block to remove them from the user's tokens array in Firestore so they are not retargeted.

Can the block send to a user ID instead of an FCM token?

Not directly. FCM addresses devices by registration token, not by user. The normal pattern is: store the user's tokens in Firestore under users/{user_id}, use a Get Document block to fetch them, then pass the token array to the Send Notification block.

Can I query subcollections?

The current block queries top-level collections. Nested or subcollection queries (for example, users/{uid}/orders) are on the roadmap. As a workaround, store denormalised data in a top-level collection keyed by user ID.

How do I test the block before going live?

Create a sandbox Firebase project with a few test documents. Connect it as a separate ChatMaxima integration, point the block at it, and run the flow from the Preview mode in Studio. Switch the block to the production integration once you are satisfied.

Troubleshooting

Verify & Save fails with "Credential rejected by Firestore"

  1. Open your Firebase project and confirm Cloud Firestore is enabled (Console → Firestore Database)
  2. Check that the service account has at least the Cloud Datastore User role (IAM → Service Accounts)
  3. Make sure you pasted the entire JSON file, including the private_key field with \n newline escapes intact
  4. Regenerate the private key if the original file was edited or partially copied

The block shows "Firebase integration not found"

  1. Confirm the integration exists under Dashboard → Integrations and is active
  2. If you created the integration recently, refresh the block modal using the refresh button next to the integration dropdown
  3. Delete and recreate the integration if the credential was rotated in Firebase

Firestore returns "Document not found" (404)

  1. Verify the collection name is spelled exactly as it appears in Firebase (case-sensitive)
  2. Check the document ID. If it comes from a variable, inspect the conversation log to see the actual value being substituted
  3. Remember that Firestore treats a missing document differently from an empty one. The block returns not_found: true in the response variable so you can branch on it

FCM notification does not arrive on the device

  1. Confirm the FCM token is valid. Tokens expire when the app is uninstalled or reinstalled
  2. Check the device has notification permissions granted for your app
  3. Inspect the response variable. A successful send returns message_name. A failure returns error and often an error_code like UNREGISTERED
  4. Verify the device is not in battery-saver mode or blocked by system-level Do Not Disturb

Topic send succeeds but no one receives it

  1. Topic delivery is best-effort and can take up to a minute
  2. Confirm devices have actually subscribed to the topic (messaging().subscribeToTopic('premium-users') on the client)
  3. Topic names are case-sensitive and cannot start with /topics/ in the v1 API. Use just the name, for example premium-users

The response variable is empty

  1. Make sure you filled in the Store the response in variable field on the block
  2. Check the variable name does not collide with a reserved keyword or another block's variable
  3. Inspect the conversation log to see the raw result of the Firebase call

Next Steps