Kellen
Kellen

Reputation: 1032

Firebase functions for push notification - "Error: Exactly one of topic, token or condition is required"

I attempting to send out push notifications using cloud functions on Firebase. The end goal is to push a notification to all users each time someone writes to a specific location in the database /model_outputs/real_estate. I've confirmed that the function activates when I manually create a node in the database. Nonetheless, when it runs, I'm seeing this error:

Error: Exactly one of topic, token or condition is required
    at FirebaseMessagingError.FirebaseError [as constructor] (/srv/node_modules/firebase-admin/lib/utils/error.js:42:28)
    at FirebaseMessagingError.PrefixedFirebaseError [as constructor] (/srv/node_modules/firebase-admin/lib/utils/error.js:88:28)
    at new FirebaseMessagingError (/srv/node_modules/firebase-admin/lib/utils/error.js:254:16)
    at Object.validateMessage (/srv/node_modules/firebase-admin/lib/messaging/messaging-types.js:46:15)
    at Messaging.send (/srv/node_modules/firebase-admin/lib/messaging/messaging.js:216:27)
    at children.map.child (/srv/index.js:59:37)
    at Array.map (<anonymous>)
    at admin.database.ref.once.then.then.children (/srv/index.js:50:24)
    at <anonymous>
    at process._tickDomainCallback (internal/process/next_tick.js:229:7)
  errorInfo: 
   { code: 'messaging/invalid-payload',
     message: 'Exactly one of topic, token or condition is required' },
  codePrefix: 'messaging'

Here's my function:

exports.sendNoti =
    functions.database.ref('/model_outputs/real_estate')
    .onWrite((change, context) => {

  return admin.database().ref("/fcmTokens").once('value')
      .then(snap => {
          let children = [];
          snap.forEach(child_snap => {
              children.push(child_snap.val());
              console.log('get token'); // build children
          });

          return children;
      })
      .then(children => {
          children.map(child => {
              let message = {
                  notification: {
                      title: "test",
                      body: "body"
                  },
                  token: child.device_token
              }

              admin.messaging().send(message).catch(console.log);
          });

          return null;
      })
      .then( () => { 
          return notif.ref.remove(); // consume send request
      })
      .catch(console.log);

});

I have to admit that I did not write this function, so if it can be improved, I'd greatly appreciate it. My angular and javascript knowledge is fairly basic.

You can see that I'm attempting to pass my user tokens into an array, and then send a message out to all of those users. The tokens are being stored at /fcmTokens in my database as such:

enter image description here

Upvotes: 3

Views: 3203

Answers (1)

gso_gabriel
gso_gabriel

Reputation: 4660

Considering the message error, it seems that the value in the child.device_token variable is not correctly set and is being send without a value. I would recommend you to print it right before sending the value and confirming it.

Once you have done that and confirmed that the issue is there, just change the way you sending the value in token, so you can send the correct value in the message.

Upvotes: 1

Related Questions