Skip to content

FCM: send()/sendEachForMulticast() with fid return NotRegistered for a FID that Console delivers to at the same moment #3288

Open

Description

@Julienog3

[READ] Step 1: Are you in the right place?

Yes — this is about the code in firebase-admin-node itself (Messaging.send() / Messaging.sendEachForMulticast() FID targeting).

[REQUIRED] Step 2: Describe your environment

  • Operating System version: Ubuntu 24.04.4 LTS (WSL2, kernel 6.6.114.1-microsoft-standard-WSL2)
  • Firebase SDK version: firebase-admin 14.5.0 (also reproduces on ^14.4.0); client-side firebase 12.19.0 / @firebase/messaging 0.13.3
  • Firebase Product: Cloud Messaging (FCM) — Firebase Installation ID (FID) targeting
  • Node.js version: 22.23.x
  • NPM version: 10.8.2 (package management via pnpm workspaces; npm version given for reference)

[REQUIRED] Step 3: Describe the problem

Steps to reproduce:

  1. Client registers for push notifications using the new FID-based API: register(messaging, { vapidKey, serviceWorkerRegistration }) from firebase/messaging.
    onRegistered fires with FID ceewOt8IieuDcWg1YUkduN.
  2. In the Firebase Console → Cloud Messaging → Compose notification → Send test message, the same FID is pasted into "Firebase Installation ID or FCM registration
    token". Delivery succeeds.
  3. From a Node backend using firebase-admin, both of the following are called for the same FID and both fail:
    await getMessaging().send({
      fid: 'ceewOt8IieuDcWg1YUkduN',
      notification: { title, body },
    });
    // and
    await getMessaging().sendEachForMulticast({
      fids: ['ceewOt8IieuDcWg1YUkduN'],
      notification: { title, body },
    });
    Both reject / return success: false with a NotRegistered error (see Relevant Code for the full error object).
  4. Immediately after step 3's failure (within the same minute), repeating step 2 (Console test send) with the identical FID succeeds again.

This rules out:

  • Propagation delay (Console succeeds within the same minute as the failed Admin SDK calls, both before and after).
  • A multicast-specific bug (reproduces identically on both send() and sendEachForMulticast()).
  • Project/config mismatch (firebase use confirms the same project, refpro-app-staging, as the client's VITE_FIREBASE_PROJECT_ID).

Note: this reproduction was observed while running the backend via the Firebase Functions emulator (firebase emulators:start --only functions), authenticated
via a firebase login user session (no GOOGLE_APPLICATION_CREDENTIALS / gcloud ADC configured locally) rather than a deployed function's service account.
Re-testing against a real deployed Cloud Function (with its actual runtime service account) is still pending on our side — flagging this in case the discrepancy turns
out to be credential-identity-related rather than an SDK bug; will update this issue once confirmed either way.

Possibly related: #2970 reports Console succeeding while Admin SDK's sendEachForMulticast() fails with a 404, but with a different error shape (raw HTML, not a
structured NotRegistered error) and using legacy tokens rather than FIDs — closed by the reporter without explanation, so inconclusive whether it's the same root
cause.

Relevant Code:

import { getMessaging } from 'firebase-admin/messaging';

const response = await getMessaging().sendEachForMulticast({
  fids: ['ceewOt8IieuDcWg1YUkduN'],
  notification: { title: 'Test', body: 'Test' },
});
// response.responses[0] => { success: false, error: FirebaseMessagingError }
FirebaseMessagingError: NotRegistered
  code: 'messaging/installation-id-not-registered',
  cause: RequestResponseError: Server responded with status 404.
  httpResponse: { status: 404, ... }
  codePrefix: 'messaging'

Activity

  1. Doris-Ge commented on Oct 28, 2026

    @Doris-Ge
    Contributor

    Hi @Julienog3,

    Thanks for reporting this issue!

    Our database shows the app instance with FID ceewOt8IieuDcWg1YUkduN is still registered with FCM via a legacy token/getToken(), not a FID/register(). sendEachForMulticast() cannot target FIDs if the instance was registered using the deprecated getToken() API.

    To help us narrow this down, could you check a few things?

    • Are you still using the getToken() API? If your app uses this alongside the new API, it will cause this conflict, so please use either getToken() or register().
    • Are you using the firebase-functions SDK? If so, this behavior is expected. The register() API is not yet compatible with the firebase-functions SDK, so please continue using the deprecated getToken() API for now.

    If neither of those applies, there may be a race condition in the JS SDK causing the FID registration to fail. In that case, please file a Firebase support ticket with your client-side implementation and the app instance state (e.g., brand new install vs. upgrade and its FID) so we can investigate further.

    Workaround:
    In the meantime, try clearing the app cache, retrying the register() call, waiting for it to complete, and then calling sendEachForMulticast() with the new FID from onRegistered().

    Note on the Firebase Console:
    It is a known bug that the Console currently allows targeting an FID that hasn't been properly registered with FCM as a messaging target. We are aware of this discrepancy and are actively working on a fix.

    Sorry for the confusion!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions