Ad

Firebase-admin: Get Token Of Failed Notification Delivery Result

Let's say we want to send a notification to two registrationTokens (only Android devices, no iOS) like this:

const tokens = ['tokenA', 'tokenB'];

const payload = {badge: 1, title: 'Hello', body: 'world'};
const options = {priority: 'high',contentAvailable: false, timeToLive: 60 * 60 * 24};

const admin = FirebaseAdmin.initializeApp({/*config here...*/});

admin.messaging().sendToDevice(deviceTokens, payload, options)
  .then((response) => {

    response.results.forEach((deviceResult) => {
      if (deviceResult.error) {
        console.log('Delivery failed. Showing result:\n', deviceResult);
      }
    });

});

The user who's device once registered with tokenB deleted the app from his device. Therefore the token is not registered anymore with firebase. The error object looks like this then:

Delivery failed. Showing result:


{"error":
  {
    "code":"messaging/registration-token-not-registered",
    "message":"The provided registration token is not registered. A previously valid registration token can be unregistered for a variety of reasons. See the error documentation for more details. Remove this registration token and stop using it to send messages."
  }
}

The Problem: My problem is, that I only know that one of the deliveries failed. But I don't know to which token the error is related. Therefore I cannot remove the outdated token from the database.

The Question: Is there a way to find out for which tokens the deliveries have failed?

Github Issue Link: https://github.com/firebase/firebase-admin-node/issues/600

Ad

Answer

You need to use the index in forEach and get the token from your array you passed in sendToDevice.

Official docs: https://firebase.google.com/docs/reference/admin/node/admin.messaging.MessagingDevicesResponse

This seems like a hack but it works for me when I have multiple device tokens of a single user as I have to store new one whenever they login.

const tokens = ['tokenA', 'tokenB'];

const payload = {badge: 1, title: 'Hello', body: 'world'};
const options = {priority: 'high',contentAvailable: false, timeToLive: 60 * 60 * 24};

const admin = FirebaseAdmin.initializeApp({/*config here...*/});

admin.messaging().sendToDevice(deviceTokens, payload, options)
  .then((response) => {

    response.results.forEach((deviceResult,index) => {
      if (deviceResult.error) {
        let failedToken = tokens[index];
        // Now use this token to delete it from your DB, or mark it failed according to your requirements.
      }
    });

});

This method is also used in firbease samples as well: https://github.com/firebase/functions-samples/blob/master/fcm-notifications/functions/index.js

Ad
source: stackoverflow.com
Ad