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}.tokensarray).
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
- Go to Dashboard → Integrations and click Add Integration
- Select Firebase from the platform dropdown
- Enter a name (for example,
Production FirebaseorMy App Firestore) so you can recognise it later - Paste the full contents of the service account JSON file into the Service Account JSON field
- 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
- Open your chatbot in Studio
- Right-click the canvas (or drag from the left sidebar) and pick Firebase under External Integrations
- Double-click the block to open its configuration
- Select the integration you created in Step 1 from the Select Integration dropdown
- 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.
| Operation | Category | What It Does |
|---|---|---|
| Get Document | Firestore | Reads a single document by collection and document ID |
| Add Document | Firestore | Creates a new document. Firestore generates the ID automatically if you leave it blank |
| Set Document | Firestore | Overwrites the document at a specific ID. Replaces all fields |
| Update Document | Firestore | Merges only the fields you provide into an existing document |
| Delete Document | Firestore | Removes a document at a specific ID |
| Query Collection | Firestore | Filters, orders, and limits a collection of documents |
| Send Notification | Cloud Messaging | Pushes 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.
| Field | Description |
|---|---|
| Collection | Firestore collection name (for example, users, orders). Pick from the detected list or type a new one |
| Document ID | The ID to read. Supports variables like {user_id} |
| Store the response in variable | Name 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}).
| Field | Description |
|---|---|
| Collection | Target collection |
| Document ID (optional) | Leave blank for auto ID, or provide a custom one |
| Field Mapping | Key/value rows. Keys are Firestore field names, values can be literals or {variable} references |
| Store the response in variable | The 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.
| Field | Description |
|---|---|
| Collection | Collection to query |
| Query Filters | Rows of field, operator, value. Combined with AND |
| Order By Field | Optional field name to sort by |
| Order Direction | Ascending or Descending |
| Limit | Maximum number of documents to return. Leave blank for no limit |
Supported filter operators:
| Operator | Meaning |
|---|---|
EQUAL | Field equals value |
NOT_EQUAL | Field does not equal value |
LESS_THAN | Field is less than value |
LESS_THAN_OR_EQUAL | Field is less than or equal to value |
GREATER_THAN | Field is greater than value |
GREATER_THAN_OR_EQUAL | Field is greater than or equal to value |
ARRAY_CONTAINS | Field is an array that contains value |
IN | Field value is one of the listed values |
ARRAY_CONTAINS_ANY | Field array contains any of the listed values |
NOT_IN | Field value is none of the listed values |
Send Notification
Sends an FCM push notification. Choose one of three targets:
| Send To | When to Use |
|---|---|
| A Single Device | One specific FCM registration token |
| Multiple Devices | Multicast to many tokens in one step. Accepts a variable that resolves to a JSON array, a comma-separated string, or a native array |
| A Topic | Broadcast to every device subscribed to a topic (for example, premium-users) |
Configuration fields:
| Field | Description |
|---|---|
| FCM Token / Tokens / Topic | The recipient, depending on target type. Variables supported |
| Notification Title | Bold headline shown in the push notification |
| Notification Body | Message text shown below the title |
| Data Payload | Optional 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.
- Question Block: Capture or verify
{user_id} - Firebase Block (Get Document): Collection
users, Document ID{user_id}, store result in{user_data} - Condition Block: Branch on
{order_status} == "confirmed" - Firebase Block (Send Notification, Multiple Devices): Tokens
{user_data.data.tokens}, titleOrder confirmed, bodyHi {user_data.data.name}, your order {order_id} is on its way - 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.
- Question Block: Ask for
{name},{email},{phone} - Firebase Block (Add Document): Collection
chatbot_leads, fieldsname={name},email={email},phone={phone},source=chatbot - 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.
- Firebase Block (Query Collection): Collection
bookings, filterslot_id EQUAL {slot_id}andstatus NOT_EQUAL cancelled, limit1, store in{existing_bookings} - Condition Block: Branch on whether
{existing_bookings}is empty - On empty: Firebase Block (Add Document) to create the booking, then Message Block to confirm
- 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.
- Trigger Block: Admin triggers the flow with a Campaign
- Firebase Block (Send Notification, Topic): Topic
premium-users, titleNew feature released, bodyTap to try it out, datascreen=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.
- Firebase Block (Send Notification, Multiple Devices): Store result in
{push_result} - Condition Block: Branch on whether
{push_result.invalid_tokens}is non-empty - Code Block or API Block: Compute the pruned token list
- Firebase Block (Update Document): Collection
users, Document ID{user_id}, fieldtokens={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
tokensfield 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
UNREGISTEREDwhen a token is dead. Use theinvalid_tokensfield 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"
- Open your Firebase project and confirm Cloud Firestore is enabled (Console → Firestore Database)
- Check that the service account has at least the Cloud Datastore User role (IAM → Service Accounts)
- Make sure you pasted the entire JSON file, including the
private_keyfield with\nnewline escapes intact - Regenerate the private key if the original file was edited or partially copied
The block shows "Firebase integration not found"
- Confirm the integration exists under Dashboard → Integrations and is active
- If you created the integration recently, refresh the block modal using the refresh button next to the integration dropdown
- Delete and recreate the integration if the credential was rotated in Firebase
Firestore returns "Document not found" (404)
- Verify the collection name is spelled exactly as it appears in Firebase (case-sensitive)
- Check the document ID. If it comes from a variable, inspect the conversation log to see the actual value being substituted
- Remember that Firestore treats a missing document differently from an empty one. The block returns
not_found: truein the response variable so you can branch on it
FCM notification does not arrive on the device
- Confirm the FCM token is valid. Tokens expire when the app is uninstalled or reinstalled
- Check the device has notification permissions granted for your app
- Inspect the response variable. A successful send returns
message_name. A failure returnserrorand often anerror_codelikeUNREGISTERED - 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
- Topic delivery is best-effort and can take up to a minute
- Confirm devices have actually subscribed to the topic (
messaging().subscribeToTopic('premium-users')on the client) - Topic names are case-sensitive and cannot start with
/topics/in the v1 API. Use just the name, for examplepremium-users
The response variable is empty
- Make sure you filled in the Store the response in variable field on the block
- Check the variable name does not collide with a reserved keyword or another block's variable
- Inspect the conversation log to see the raw result of the Firebase call
Next Steps
- API Block - Call any external REST API from your flow
- Webhook Block - Receive inbound HTTP calls into your flow
- Condition Block - Branch the flow on variable values
- Studio Overview - Explore all block types and flow builder features