【问题标题】:Not All Notifications Show after being Offline离线后并非所有通知都显示
【发布时间】:2020-10-15 16:49:09
【问题描述】:

我正在测试将物理 (android) 设备转为飞行模式(无 wifi)的情况。当我将设备恢复在线时,我想接收所有通知。

目前我只收到多个通知之一。

我搜索了有关此案例的文档 Setting the lifespan of a message 并找到了 time_to_live 参数。通过这个参数,我可以编辑通知的生命周期,但我没有使用它,因为默认情况下它设置为 4 周。就我而言,几秒钟/几分钟后,我将设备转为在线。

以下函数在可调用的 Cloud Function 中实现,该函数在设备在线时触发并正常工作。

这是我发送消息的方式:

async function notifyParticipantForRegistrationStatus(
  data: any,
  participantDeleted: boolean
) {
  const uid = data.uid;
  const courseId = data.courseId;
  const courseEventSnapshot = await firestore
    .collection("CourseEvents")
    .doc(courseId)
    .get();
  const courseEvent = courseEventSnapshot.data() as CourseEvent;

  // get tokens for this participant
  const registrationTokens: string[] = [];
  await firestore
    .collection("Users")
    .doc(uid)
    .collection("Tokens")
    .get()
    .then((querySnapshot) => {
      querySnapshot.forEach(function (doc) {
        const tokenObj = doc.data() as Token;
        registrationTokens.push(tokenObj.token);
      });
    })
    .catch((error) => {
      console.error(`registrationTokens: ${registrationTokens}`);
      console.error(error);
    });
  // transform date from utc to german
  const d = utcSecondsToGermanDate(courseEvent.start.seconds);

  // send notification to the deletedParticipant
  if (registrationTokens.length > 0) {
    const message = {
      notification: {
        title: `Kurs ${courseEvent.courseEventTitle}`,
        body: participantDeleted
          ? `Du wurdest vom Kurs ${courseEvent.courseEventTitle} an den ${d.getDate()}.${
              d.getMonth() + 1 //getMonth() starts from 0
            }.${d.getFullYear()} um ${d.getHours()}:${d.getMinutes()} entfernt. Deine Einheit wurde storniert.`
          : `Du wurdest zum Kurs ${courseEvent.courseEventTitle} an den ${d.getDate()}.${
              d.getMonth() + 1 //getMonth() starts from 0
            }.${d.getFullYear()} um ${d.getHours()}:${d.getMinutes()} registriert.`,
      },
      tokens: registrationTokens,
    } as admin.messaging.MulticastMessage;

    fcm
      .sendMulticast(message)
      .then((response) => {
        if (response.failureCount > 0) {
          const failedTokens: string | string[] = [];
          response.responses.forEach((resp, idx) => {
            if (!resp.success) {
              failedTokens.push(registrationTokens[idx]);
            }
          });
          console.log("List of tokens that caused failures: " + failedTokens);
        }
      })
      .catch((error) => {
        console.error(error);
      });
  }
}

【问题讨论】:

    标签: typescript google-cloud-functions firebase-cloud-messaging


    【解决方案1】:

    我几乎可以肯定您已经阅读了第一个文档,但我引用它只是为了记录。

    来自documentation

    FCM 通常在消息发送后立即发送消息。但是,这可能并不总是可能的。例如,如果平台是 Android,设备可能已关闭、离线或不可用。或者 FCM 可能会故意延迟消息,以防止应用消耗过多资源并对电池寿命产生负面影响。

    发生这种情况时,FCM 会存储消息并在可行时尽快发送。虽然这在大多数情况下都很好,但也有一些延迟消息可能永远不会被传递的应用程序。例如,如果消息是来电或视频聊天通知,则它仅在通话终止前的短时间内有意义。或者,如果消息是一个活动的邀请,如果在活动结束后收到它是没有用的。

    我相信您可以将通知消息设置为non-collapsible,这意味着它们是关键消息,将单独发送,因为每条消息都有不同的内容。

    我还认为您可能希望使用high-priority FCM messages,因为即使设备处于打盹状态,这也能可靠地唤醒应用程序。

    另见:

    【讨论】:

    • 属性time_to_live在android中应该不是问题,因为默认设置为4周。此外,我确实研究了有关不可折叠选项的文档。显然,没有方法可以使通知不可折叠,如下所述:stackoverflow.com/questions/50288118/…
    【解决方案2】:

    我确实找到了解决方案。感谢@sllopis,我发现 通知 默认情况下是可折叠的,但 数据消息 不是。因此,我确实将我的信息更改为:

    const message = {
          data: {
            title: `Kurs ${courseEvent.courseEventTitle}`,
            body: participantDeleted
              ? `Du wurdest vom Kurs ${
                  courseEvent.courseEventTitle
                } an den ${d.getDate()}.${
                  d.getMonth() + 1 //getMonth() starts from 0
                }.${d.getFullYear()} um ${d.getHours()}:${d.getMinutes()} entfernt. Deine Einheit wurde storniert.`
              : `Du wurdest zum Kurs ${
                  courseEvent.courseEventTitle
                } an den ${d.getDate()}.${
                  d.getMonth() + 1 //getMonth() starts from 0
                }.${d.getFullYear()} um ${d.getHours()}:${d.getMinutes()} registriert.`,
            click_action: "FLUTTER_NOTIFICATION_CLICK",
          },
          tokens: registrationTokens,
        } as admin.messaging.MulticastMessage;
    

    现在我可以在设备上线后收到多个“通知”。

    注意!!

    要在您的应用处于后台时捕获并显示此类消息(数据),您必须使用 onBackgroundMessage 而不是 onLaunchonResume强>功能。这是一篇帮助我的文章:https://medium.com/@sylvainduch/firebase-messaging-catch-them-all-3f9c594734d7

    要使 onBackgroundMessage 充分发挥作用,您必须按照文档中的步骤操作:https://pub.dev/packages/firebase_messaging

    并将此处提供的解决方案添加到新创建的应用程序类中:@varadkulk 提供的https://github.com/MaikuB/flutter_local_notifications/issues/238

    至少对于安卓来说。

    【讨论】:

      猜你喜欢
      • 2016-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-28
      • 2019-11-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多