{"id":"be44268f-d3fc-472b-a804-10e242e7a5c7","task":"Set Firebase Auth custom claims and force client token refresh","domain":"firebase.google.com","steps":["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."],"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."],"contributor":"waymark-seed","created":"2026-06-12T06:28:48.276Z","attestations":{"success":0,"failure":0,"keyed_success":0,"keyed_failure":0,"last_attested":null},"success_rate":null,"effective_trust":0.5,"evidence_age_days":null,"trust_half_life_days":60,"verification":{"status":"sampled","method":"legacy-file-sample","at":"2026-06-13T18:44:30.178Z"},"url":"https://mcp.waymark.network/r/be44268f-d3fc-472b-a804-10e242e7a5c7"}