0

I was following the tutorial for cloud functions and modified the code a bit to fit my project.

const functions = require('firebase-functions');
const admin = require('firebase-admin');

admin.initializeApp(functions.config().firebase);

exports.sendNotif = functions.database().ref("/admin/announcement_record").onCreate(event =>{
    const snapshot = event.data;

    // Notification details.
    const text = snapshot.val().text;
    const payload = {
        notification: {
            title: "New Announcement",
            body: text ? (text.length <= 100 ? text : text.substring(0, 97) + '...') : ''
        }
    };

    // Get the list of device tokens.
    return admin.database().ref("/admin/fcmtokens").once('value').then(allTokens => {
        if (allTokens.val()) {
          // Listing all tokens.
          const tokens = Object.keys(allTokens.val());

          // Send notifications to all tokens.
          return admin.messaging().sendToDevice(tokens, payload).then(response => {
            // For each message check if there was an error.
            const tokensToRemove = [];
            response.results.forEach((result, index) => {
              const error = result.error;
              if (error) {
                console.error('Failure sending notification to', tokens[index], error);
                // Cleanup the tokens who are not registered anymore.
                if (error.code === 'messaging/invalid-registration-token' ||
                    error.code === 'messaging/registration-token-not-registered') {
                  tokensToRemove.push(allTokens.ref.child(tokens[index]).remove());
                }
              }
            });
            return Promise.all(tokensToRemove);
          });
        }
      });
});

When trying to deploy it I get this

28:79 warning Expected to return a value at the end of arrow function consistent-return
29:3 error Each then() should return a value or throw promise/always-return
34:12 warning Avoid nesting promises promise/no-nesting

Looking for advice on how to fix or a fix to continue the tutorial.

sleepy_jc
  • 23
  • 5
  • might help you https://stackoverflow.com/questions/48750847/each-then-should-return-a-value-or-throw-when-using-promises – Peter Haddad Mar 30 '18 at 07:24
  • checked it, but not sure how to apply it because it said not to use the Promise constructor, which is the case too here. Unless I missed someting. – sleepy_jc Mar 30 '18 at 07:55

1 Answers1

1

I'm going to trim this down a bit, but roughly, the error[:] Each then() should return a value or throw is probably the thing keeping you from moving forward. In your promise, you'll need to always return a promise or throw an error from every branch - here's a little documentation and examples.

So, you'll need to add some type of return to the outside of your if statement, like so:

return admin.database().ref("/admin/fcmtokens").once('value').then(allTokens => {
    if (allTokens.val()) {
      // Listing all tokens.
      const tokens = Object.keys(allTokens.val());

      // Send notifications to all tokens.
      return admin.messaging().sendToDevice(tokens, payload).then(response => {
        // [...snip...]
        return Promise.all(tokensToRemove);
      });
    }
    return null; // explicitly return `null`.
//  ^^^^^^
  });
});

That should help you get past the lint errors and continue on your way. The first warning is related to this error (I think). To fix the second warning, you'd have to do a little more reorganizing, but I think that's not necessary to keep moving forward.

Nicolas Garnier
  • 12,134
  • 2
  • 42
  • 39
bkend
  • 131
  • 4