Skip to content Skip to sidebar Skip to footer

Firebase Cloud Messaging Sendtodevice Works Properly But Sendmulticast Fails For The Same List Of Tokens

For certain types of messages, I want to target users by FIRTokens vs topic, which are stored in my real-time database. I load these tokens with async/await and then decide if I wa

Solution 1:

I think it's an issue of using a different payload structure.

This is the old one (without iOS specific info):

varpayload= {
    notification: {
      title:title,
      body:messageText,
      sound:"default",
    },
    data: {
      messageID:messageID,
      messageTimestamp:messageTimestamp,
    },
  };

Whereas this is the new version (apns has iOS specific info)

varpayload= {
    notification: {
      title:title,
      body:messageText,
    },
    data: {
      messageID:messageID,
      messageTimestamp:messageTimestamp,
    },
    apns: {
      payload: {
        aps: {
          sound:"default",
        },
      },
    },
  };

With the new structure, both send and sendMulticast are working properly. Which would fail to send or give errors like apns key is not supported in payload.

The new function:

functions.database
  .ref("/discussionMessages/{autoId}/")
  .onCreate(async (snapshot, context) => {
    // console.log("Snapshot: ", snapshot);try {
      const groupsRef = admin.database().ref("people/groups");
      const adminUsersRef = groupsRef.child("admin");
      const filteredUsersRef = groupsRef.child("filtered");
      const filteredUsersSnapshot = await filteredUsersRef.once("value");
      const adminUsersSnapshot = await adminUsersRef.once("value");
      var adminUsersFIRTokens = {};
      var filteredUsersFIRTokens = {};

      if (filteredUsersSnapshot.exists()) {
        filteredUsersFIRTokens = filteredUsersSnapshot.val();
      }
      if (adminUsersSnapshot.exists()) {
        adminUsersFIRTokens = adminUsersSnapshot.val();
      }

      // console.log(//   "Admin and Filtered Users: ",//   adminUsersFIRTokens,//   " ",//   filteredUsersFIRTokens// );const topicName = "SpeechDrillDiscussions";
      const message = snapshot.val();

      // console.log("Received new message: ", message);const senderName = message.userName;
      const senderCountry = message.userCountryEmoji;
      const title = senderName + " " + senderCountry;
      const messageText = message.message;
      const messageTimestamp = message.messageTimestamp.toString();
      const messageID = message.hasOwnProperty("messageID")
        ? message.messageID
        : undefined;
      const senderEmailId = message.userEmailAddress;
      const senderUserName = getUserNameFromEmail(senderEmailId);

      const isSenderFiltered = filteredUsersFIRTokens.hasOwnProperty(
        senderUserName
      );

      console.log(
        "Will attempt to send notification for message with message id: ",
        messageID
      );

      var payload = {
        notification: {
          title: title,
          body: messageText,
        },
        data: {
          messageID: messageID,
          messageTimestamp: messageTimestamp,
        },
        apns: {
          payload: {
            aps: {
              sound: "default",
            },
          },
        },
      };
      console.log("Is sender filtered? ", isSenderFiltered);

      if (isSenderFiltered) {
        adminFIRTokens = Object.values(adminUsersFIRTokens);
        console.log("Sending filtered notification with sendMulticast()");
        payload.tokens = adminFIRTokens; //Needed for sendMulticastreturn admin
          .messaging()
          .sendMulticast(payload)
          .then((response) => {
            console.log(
              "Sent filtered message (using sendMulticast) notification: ",
              JSON.stringify(response)
            );
            if (response.failureCount > 0) {
              const failedTokens = [];
              response.responses.forEach((resp, idx) => {
                if (!resp.success) {
                  failedTokens.push(adminFIRTokens[idx]);
                }
              });
              console.log(
                "List of tokens that caused failures: " + failedTokens
              );
            }
            returntrue;
          });
      } else {
        console.log("Sending topic message with send()");
        payload.topic = topicName;
        return admin
          .messaging()
          .send(payload)
          .then((response) => {
            console.log(
              "Sent topic message (using send) notification: ",
              JSON.stringify(response)
            );
            returntrue;
          });
      }
    } catch (error) {
      console.log("Notification sent failed:", error);
      returnfalse;
    }
  });

Post a Comment for "Firebase Cloud Messaging Sendtodevice Works Properly But Sendmulticast Fails For The Same List Of Tokens"