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

Flutter中Firebase Messaging通知无故延迟批量送达问题求助

通知延迟批量推送的问题排查与修复

核心问题分析

你的Cloud Functions代码存在几个关键问题,直接导致通知延迟或批量推送:

  1. forEach未等待异步操作完成
    forEach循环不会等待内部的异步函数执行完毕,Cloud Functions可能在所有推送请求发送前就提前终止,导致消息被缓存后批量触发。

  2. 仅使用data消息,未利用FCM的notification字段
    当前消息只有data字段,Android/iOS在后台状态下不会自动展示这类通知,需要客户端手动处理,这会增加延迟;而notification字段的消息会由系统直接展示,及时性更高。

  3. 错误处理与日志缺失
    未对sendMulticast的返回结果做处理,无法得知哪些推送失败,也没有重试机制,失败的消息可能被延迟重试。

修复后的代码示例

exports.messageTrigger = functions.firestore.document('/Messages/{messageID}').onCreate(async (snapshot, context) => {
  function capitalizeFirstLetter(string) {
    return string.charAt(0).toUpperCase() + string.slice(1);
  }

  const currentRoomUsers = snapshot.data().members;
  const senderID = snapshot.data().senderID;
  const roomName = capitalizeFirstLetter(snapshot.data().room);
  const messageType = snapshot.data().type;

  // 用for...of替代forEach,确保异步操作顺序执行
  for (const userID of currentRoomUsers) {
    if (userID === senderID) continue; // 跳过发送者

    try {
      const doc = await db.collection('Users').doc(userID).get();
      if (!doc.exists) {
        console.log(`用户 ${userID} 不存在`);
        continue;
      }

      const deviceTokens = doc.data()['Device_token'];
      if (!deviceTokens || deviceTokens.length === 0) {
        console.log(`用户 ${userID} 无设备令牌`);
        continue;
      }

      // 构建包含notification和data的消息
      const message = {
        tokens: deviceTokens,
        // 系统直接展示的通知内容
        notification: {
          title: `来自${roomName}的新消息`,
          body: messageType === 'm.text' ? '发送了一条新消息' : 
                messageType === 'm.start' ? '邀请你通话' : 
                messageType === 'm.image' ? '发送了一张图片' : '发送了一条新消息'
        },
        // 附加数据,供客户端处理
        data: {
          room: snapshot.data().room,
          messageID: context.params.messageID
        },
        android: {
          priority: 'high',
          notification: {
            priority: 'high',
            sound: 'default' // 确保通知有声音,提升及时性
          }
        },
        apns: {
          payload: {
            aps: {
              contentAvailable: true,
              priority: 1 // iOS高优先级,确保后台推送及时
            }
          }
        },
        priority: 'high'
      };

      const response = await admin.messaging().sendMulticast(message);
      // 记录推送结果
      console.log(`用户 ${userID} 推送完成:成功${response.successCount}条,失败${response.failureCount}条`);
      // 处理失败的推送,可添加重试逻辑
      if (response.failureCount > 0) {
        response.responses.forEach((resp, idx) => {
          if (!resp.success) {
            console.error(`令牌 ${deviceTokens[idx]} 推送失败:${resp.error}`);
          }
        });
      }
    } catch (error) {
      console.error(`处理用户 ${userID} 时出错:${error}`);
    }
  }
});

额外优化建议

  • 客户端配置检查:确保flutter_local_notifications和firebase_messaging的配置正确,Android端在AndroidManifest.xml中设置高优先级通道,iOS端开启推送权限并配置APNs证书。
  • 批量推送优化:如果一个用户有多个设备令牌,用sendMulticast是正确的;如果是多个用户,可考虑分组处理,但避免一次发送过多请求导致限流。
  • Cloud Functions资源配置:如果推送量较大,可适当提高Cloud Functions的内存和超时时间,避免因资源不足导致中断。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 05:30:43