You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firebase云函数部署报错Each then() should return a value or throw解决方法

Fixing "Each then() should return a value or throw" Error in Firebase Cloud Function

Hey there, that error stems from ESLint's promise/always-return rule—newer Firebase Cloud Function projects enforce this to ensure all asynchronous operations are properly chained, so the platform knows when your function has finished executing. Let's break down the issues in your code and fix them step by step:

1. Missing return in the Like branch's final then()

In your 'Like' logic, after handling the sendToDevice response, you only log a message but don't return anything. Add a simple return statement to satisfy the rule:

return admin.messaging().sendToDevice(tokens, payload).then(response => {
  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; // Add this line to close the Promise chain
});

2. Unreturned inner Promise in the Follow branch

In the 'Follow' section, you call followeeFollowingRef.once('value').then(...) inside the Promise.all callback, but you don't return this inner Promise. This breaks the chain, and ESLint flags it. Also, the final sendToDevice then() is missing a return:

return Promise.all([followeeUserRef.once('value')]).then(function(snaps) {
  var data = snaps[0].val();
  const fcmToken = data.FCM_TOKEN;

  // Return this inner Promise to keep the chain intact
  return followeeFollowingRef.once('value').then(function(followeeSnapshot) {
    let isFollow = followeeSnapshot.exists() ? 'YES' : 'NO';
    console.log(`FOLLOW ${isFollow}`);

    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'
      }
    };

    const tokens = fcmToken;
    console.log('FcmToken: ', tokens);

    return admin.messaging().sendToDevice(tokens, payload).then(response => {
      response.results.forEach((result, index) => {
        const error = result.error;
        if (error) {
          console.log('Error Occured:', error);
        }
      });
      console.log('User Followed');
      return null; // Add this return to close the chain
    });
  });
});

3. Default return for unhandled activity types

At the end of your function, if none of the type conditions match (e.g., a new activity type is added later), you don't return anything. Add a default return to cover this edge case:

// After all if blocks
return null;

Full Corrected Code

Here's the complete function with all fixes applied:

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 = 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; 

      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' 
        } 
      }; 

      const tokens = fcmToken; 

      return admin.messaging().sendToDevice(tokens, payload).then(response => { 
        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; // Added return
      }); 
    }); 
  } 
  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 = db.ref('USER_MANAGEMENT/USERS/'+followerUserId); 
    var followeeUserRef = db.ref('USER_MANAGEMENT/USERS/'+followeeUserId); 

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

    return Promise.all([followeeUserRef.once('value')]).then(function(snaps) { 
      var data = snaps[0].val(); 
      const fcmToken = data.FCM_TOKEN; 

      // Return inner Promise chain
      return followeeFollowingRef.once('value').then(function(followeeSnapshot) { 
        let isFollow = followeeSnapshot.exists() ? 'YES' : 'NO'; 
        console.log(`FOLLOW ${isFollow}`); 

        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' 
          } 
        }; 

        const tokens = fcmToken; 
        console.log('FcmToken: ', tokens); 

        return admin.messaging().sendToDevice(tokens, payload).then(response => { 
          response.results.forEach((result, index) => { 
            const error = result.error; 
            if (error) { 
              console.log('Error Occured:', error); 
            } 
          }); 
          console.log('User Followed'); 
          return null; // Added return
        }); 
      }); 
    }); 
  } 
  // Default return for unhandled types
  return null;
});

Older Firebase Function versions didn't enforce this ESLint rule as strictly, which is why your code worked before. These fixes ensure all Promise chains are properly closed, so Firebase knows when your function is done executing.

内容的提问来源于stack exchange,提问作者Randima Lahiru

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 09:37:51