Using the Firebase Admin SDK on your server, call admin.auth().setCustomUserClaims(uid, claimsObject) to write custom claims to the user record; this does not immediately update tokens already in circulation.
New claims are only reflected in the ID token after the next token refresh; to signal the client to refresh immediately, write the current server timestamp to a known path in Realtime Database or Firestore for that user.
On the client, listen to the database path; when a new timestamp appears that is newer than the token's issued-at time, call user.getIdToken(true) to force a token refresh.
After the forced refresh, use the new ID token for API calls; the custom claims will now be present in the decoded token payload.
To revoke all refresh tokens for a user (full session invalidation), call admin.auth().revokeRefreshTokens(uid); clients must re-authenticate after revocation.
Validate custom claims on your backend by verifying the ID token with the Admin SDK or by checking claims in a JWT verified against Firebase's JWKS endpoint.
Known gotchas
setCustomUserClaims silently overwrites the entire claims object — it does not merge; always read existing claims first if you want to add a single claim without removing others.
Custom claims are stored in the ID token, which is limited in size; Firebase enforces a maximum of 1000 bytes for the serialized claims object — exceeding this causes setCustomUserClaims to fail.
Token revocation via revokeRefreshTokens only prevents new tokens from being issued; existing short-lived ID tokens (typically valid for 1 hour) remain valid until they naturally expire unless you also check tokensValidAfterTime on each request.
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp