Each contact gets the Firebase UID as its
externalId, so a user who changes
their email keeps the same contact.
You can still deploy functions after Firebase Extensions shut down on March 31, 2027. This setup also replaces the Mailchimp and Customer.io
contact-sync extensions.
Prerequisites
- A Firebase project on the Blaze plan, which Cloud Functions require.
firebase-functions6 or later and Node.js 20 or later in yourfunctionsfolder.- A publishable key for your app, created as described in Mobile SDKs.
- A secret API key from Settings → API Keys & SMTP with the scopes
subscribers:write,automations:triggerandcommerce:write. Addsubscribers:deleteif you deploy the deletion function.
1. Store your keys
Save the secret API key in Cloud Secret Manager. It never reaches your app:functions/.env. It is not a secret:
functions/.env
2. Add the functions
Createfunctions/src/sequenzy.ts:
functions/src/sequenzy.ts
functions/src/index.ts, then deploy:
functions/src/index.ts
firebase-functions/v1). Firebase
only fires these signup and deletion events on 1st-gen functions, so the
optional functions stay 1st gen. 2nd gen only has blocking triggers, which
need Identity Platform.
3. Call the function from your app
Give the SDK an identity token provider that callssequenzyIdentityToken,
then identify the user with their Firebase email after sign-in. The function
reads the email from the Firebase ID token and ignores anything the app sends,
so the token always belongs to the signed-in user.
- iOS
- Android
- React Native
- Flutter
Add
FirebaseFunctions from the Firebase iOS SDK.us-central1, pass the same region to the
Functions client, for example Functions.functions(region: "europe-west1").
Identity tokens last 24 hours, so the SDK calls the function about once a day
per device, plus once after each sign-in. Only identify users who have an
email address: anonymous and phone-only Firebase users get a
failed-precondition error, and the SDK retries every minute.
What gets synced
Add your own fields to
syncContact as customAttributes, for example a plan
or signup source. For values that change often, use setProfile in the app
or Update Subscriber from another
function.
New contacts join your workspace default lists and start sequences with a
Contact Added trigger. The workspace double opt-in setting applies. To skip
both, add enrollInSequences: false or optInMode: "confirmed" to the
request body; see Create Subscriber.
Existing users
The functions only add users when they next open the app or sign up. To import users who signed up earlier, export them withfirebase auth:export users.json --format=json and send the ones with
emailVerified: true to Create Subscriber Import
in batches of up to 5,000, with localId as externalId. Convert each user’s
createdAt (milliseconds in the export) to an ISO date to keep their signup
date. Imports do not start sequences unless you pass enrollInSequences: true.
Troubleshooting
permission-deniedfrom the function: the user’s email is not verified. Send a verification email with Firebase Auth, then callidentifyagain after they verify.unavailablefrom the function: Sequenzy rejected the token request. The function log shows the status and error. A403means the API key is missing a scope listed above, and a400means the email cannot be a contact, for example because it is suppressed.not-foundorinternalin the app: the function is not deployed in the region the client calls, or the app uses a different Firebase project.- Events do nothing after sign-in: the email passed to
identifymust be the Firebase user’s email. A token minted for one email does not work for another.
FAQ
Do I still need a backend?
Do I still need a backend?
No. The callable function is the backend. It holds the secret API key and
checks the Firebase ID token, so your app never sees the key.
What about Sign in with Apple private relay addresses?
What about Sign in with Apple private relay addresses?
They become contacts like any other email. Apple only forwards mail from
domains you register in your Apple Developer account, so add your
Sequenzy sending domain there.
Can I sync Firestore data?
Can I sync Firestore data?
Yes. Add a Firestore trigger, such as
onDocumentWritten("users/{uid}"),
that sends the fields you need to
Update Subscriber with
PATCH /api/v1/subscribers/external?externalId={uid}.Can I use Firebase Analytics events?
Can I use Firebase Analytics events?
Not directly. Turn on the BigQuery export in Firebase and import the
events with warehouse sync.