Randima Lahiru
Randima Lahiru

Reputation: 365

Each then() should return a value or throw error in firebase cloud function

I am writing a cloud function for firebase using javascript , while I deploy a function a error occurring and terminate deploy process.

Error : Each then() should return a value or throw

How I resolve this error?

Below I attached my code.

exports.sendNotificationForLikeOrFollow = functions.database.ref('/USER_MANAGEMENT/USER_ACTIVITY/{activityId}').onCreate((snap, context) => {

  var type = snap.val().ACTIVITY_TYPE;

  if (type=='Comment') {
    return; //There is a separate function for comment notification
  }

  if (type=='Like') {

    const likeUserId = snap.val().BY_USER_NODE_NAME;
    const publishedUserId = snap.val().PUBLISHED_USER_NODE_NAME;
    const puplishedContentId = snap.val().LIKE_PUBLISHED_CONTENT_NODE_NAME;
    const likedUserName = snap.val().BY_USER_NAME;
    const likedUserPhotoUrl = snap.val().BY_USER_PHOTO_URL;

    // var publishedUserRef = event.data.ref.parent.parent.child('USERS/'+publishedUserId);
    // var likedUserRef = event.data.ref.parent.parent.child('USERS/'+likeUserId);
    var publishedUserRef = db.ref("USER_MANAGEMENT/USERS/"+publishedUserId);
    var likedUserRef = db.ref("USER_MANAGEMENT/USERS/"+likeUserId);

    return Promise.all([publishedUserRef.once('value')]).then(function(snaps) {

        var data = snaps[0].val();
        const fcmToken = data.FCM_TOKEN;

          // Notification details.
          const payload = {
            notification: {
              title: '❤️ You got a new like!',
              body: likedUserName+` liked your artwork.`,
              sound: 'default',
              icon: '',
              byUserId: likeUserId,
              byUserName: likedUserName,
              type: 'Like',
              likedPuplishedContentId: puplishedContentId,
              publishedUserId: publishedUserId,
              byUserPhotoUrl: likedUserPhotoUrl,
              badge : '1'
            }
          };

          // Listing all tokens.
          const tokens = fcmToken;

          // Send notifications to all tokens.
          return admin.messaging().sendToDevice(tokens, payload).then(response => {
            // For each message check if there was an error.
            response.results.forEach((result, index) => {
              console.log('FcmToken: ', tokens);
              const error = result.error;
              if (error) {
                console.log('Error Occured:', error);
              }
            });
            console.log('User Liked');
          });
    });
  }

  if (type=='Follow') {
    const followerUserId = snap.val().BY_USER_NODE_NAME;
    const followeeUserId = snap.val().FOLLOWING_USER_NODE_NAME;
    const followerUserName = snap.val().BY_USER_NAME;
    const followerPhotoUrl = snap.val().BY_USER_PHOTO_URL;

    // var followerUserRef = event.data.ref.parent.parent.child('USERS/'+followerUserId);
    // var followeeUserRef = event.data.ref.parent.parent.child('USERS/'+followeeUserId);
    var followerUserRef = db.ref('USER_MANAGEMENT/USERS/'+followerUserId);
    var followeeUserRef = db.ref('USER_MANAGEMENT/USERS/'+followeeUserId);
    var isFollow;

    //const followeeFollowingRef = event.data.ref.parent.parent.child('FOLLOWING/'+followeeUserId+'/'+followerUserId);
    const followeeFollowingRef = db.ref('USER_MANAGEMENT/FOLLOWING/'+followeeUserId+'/'+followerUserId);

    return Promise.all([followeeUserRef.once('value')]).then(function(snaps) {

        var data = snaps[0].val(); // Get whole USER_MANAGEMENT snapshot

        const fcmToken = data.FCM_TOKEN

        followeeFollowingRef.once('value').then(function(followeeSnapshot) {

          if (followeeSnapshot.exists()) {
            isFollow = 'YES';
            console.log('FOLLOW YES');
          }else{
            isFollow = 'NO';
            console.log('FOLLOW NO');
          }

            // Notification details.
            const payload = {
              notification: {
                title: '🤗 You have a new follower!',
                body: followerUserName+` is now following you.`,
                sound: 'default',
                icon: '',
                byUserId: followerUserId,
                byUserName: followerUserName,
                type: 'Follow',
                isFollow: isFollow,
                byUserPhotoUrl: followerPhotoUrl,
                badge : '1'
              }
            };

            // Listing all tokens.
            const tokens = fcmToken;
            console.log('FcmToken: ', tokens);
            // Send notifications to all tokens.
            return admin.messaging().sendToDevice(tokens, payload).then(response => {
              // For each message check if there was an error.
              response.results.forEach((result, index) => {
                const error = result.error;
                if (error) {

                  console.log('Error Occured:', error);
                }
              });
              console.log('User Followed');
            });
      });    
    });
  }
});

This function already deploy before few years and it is working fine. But now I try to deploy same code to another project it was stopped due to above error.

Upvotes: 0

Views: 111

Answers (1)

Renaud Tarnec
Renaud Tarnec

Reputation: 83103

You don't correctly chain the different promises returned by the Firebase asynchronous methods.

Also, note that you do not need to use Promise.all() since the once() method returns only one Promise. Again, you should correctly chain the Promises, instead of using Promise.all(), which should be use for executing asynchronous methods in parallel, and not in sequence.

So, the following should do the trick (untested):

exports.sendNotificationForLikeOrFollow = functions.database.ref('/USER_MANAGEMENT/USER_ACTIVITY/{activityId}').onCreate((snap, context) => {

    var type = snap.val().ACTIVITY_TYPE;

    if (type == 'Comment') {
        return null; //There is a separate function for comment notification
    }

    if (type == 'Like') {

        const likeUserId = snap.val().BY_USER_NODE_NAME;
        const publishedUserId = snap.val().PUBLISHED_USER_NODE_NAME;
        const puplishedContentId = snap.val().LIKE_PUBLISHED_CONTENT_NODE_NAME;
        const likedUserName = snap.val().BY_USER_NAME;
        const likedUserPhotoUrl = snap.val().BY_USER_PHOTO_URL;

        var publishedUserRef = db.ref("USER_MANAGEMENT/USERS/" + publishedUserId);

        return publishedUserRef.once('value')
            .then(snaps => {

                var data = snaps[0].val();
                const fcmToken = data.FCM_TOKEN;

                // Notification details.
                const payload = {
                    notification: {
                        title: '❤️ You got a new like!',
                        body: likedUserName + ` liked your artwork.`,
                        sound: 'default',
                        icon: '',
                        byUserId: likeUserId,
                        byUserName: likedUserName,
                        type: 'Like',
                        likedPuplishedContentId: puplishedContentId,
                        publishedUserId: publishedUserId,
                        byUserPhotoUrl: likedUserPhotoUrl,
                        badge: '1'
                    }
                };

                // Listing all tokens.
                const tokens = fcmToken;

                // Send notifications to all tokens.
                return admin.messaging().sendToDevice(tokens, payload);
            })
            .then(response => {
                // For each message check if there was an error.
                response.results.forEach((result, index) => {
                    console.log('FcmToken: ', tokens);
                    const error = result.error;
                    if (error) {
                        console.log('Error Occured:', error);
                    }
                });
                console.log('User Liked');
                return null;
            });
    }

    if (type == 'Follow') {
        // See above, it is similar
    }
});

Upvotes: 1

Related Questions