Connect Firebase Auth
Push your Firebase users to Apex. The Firebase uid becomes your internal_user_id.
New users — auth().onCreate Cloud Function
// functions/index.js
const functions = require("firebase-functions");
exports.apexOnUserCreate = functions.auth.user().onCreate(async (user) => {
await fetch("https://app.apex.inc/api/v1/events", {
method: "POST",
headers: {
"content-type": "application/json",
"x-api-key": process.env.APEX_API_KEY, // apex_sk_...
},
body: JSON.stringify({
events: [
{
type: "user_signed_up",
email: user.email,
// `photoURL` is Firebase's profile-photo field — map it to the
// canonical `avatar_url` attribute for end-user photos in Apex.
data: {
userId: user.uid,
name: user.displayName,
avatar_url: user.photoURL,
},
},
],
}),
}).catch(() => {});
});
Returning users — client onAuthStateChanged
onCreate only fires once. To reconcile your existing base on next login (the passive backfill path) and to stitch the browser session, emit an identify from the client when auth state resolves:
import { getAuth, onAuthStateChanged } from "firebase/auth";
import { identify } from "@apex-inc/sdk";
onAuthStateChanged(getAuth(), (user) => {
if (user) {
// Pass the uid as your stable id; include the apex_vid cookie so the
// anonymous browser session stitches to this user.
identify(user.uid, {
email: user.email,
avatar_url: user.photoURL,
visitorId: getCookie("apex_vid"),
});
}
});
Tip
The browser identify() carries the apex_vid visitor cookie so pre-login
pageviews and experiment exposures attach to the now-known user. The
server-side onCreate function is the durable, tamper-proof signal.
Wire it up
- Create a workspace API key (
apex_sk_…) and set it as the function'sAPEX_API_KEY(firebase functions:config:setor an env var). - Deploy the function:
firebase deploy --only functions:apexOnUserCreate. - Add the client
onAuthStateChangedsnippet to your app shell. - Sign up a test user — they appear in Customers, identified.