我正在我的 flutter 应用程序中构建聊天部分。我使用 FCM 服务将通知推送为
Notifications
,而不是 only-data messages
。如果用户不在线,我遇到了 firebase 折叠通知的问题,它只会推送最后一个通知,但我依靠有效负载的通知来更新聊天和聊天消息。我必须更改为仅数据消息以避免崩溃问题。当应用程序在 Android
和 iOS
上处于前台和后台时,它正在调试模式下运行。我想测试应用程序是否被终止,结果发现,无论应用程序是在background还是termerated,直到用户打开应用程序才会收到数据消息。而如果我使用普通通知,它总是会收到。有人可以帮助我理解并解决这个问题吗?
Laravel FCM 功能:
public function sendDataMessage($deviceTokens, $data = [], $priority = "high")
{
$messaging = app('firebase.messaging');
$clean_data = $data;
if (isset($data["type"]) && $data["type"] == "chat" && $data["action"] == "receiveMessage") {
unset($clean_data["fcm_message"]);
}
$messages = [];
foreach ($deviceTokens as $token) {
try {
if (isset($data["type"]) && $data["type"] == "chat" && $data["action"] == "receiveMessage") {
$chat_message = $data["fcm_message"];
$clean_data["title"] = Chats::select("name")->find($data["chat_id"])->name;
$clean_data["body"] = $chat_message["sender"]["name"] . ": " . ($chat_message["content"]["type"] == "Text" ? $chat_message["content"]["body"] : $chat_message["content"]["type"]);
}
$messages[] = CloudMessage::withTarget('token', $token)
->withData($clean_data)
// ->withNotification(Notification::create("Asdasdoqoijwdioqs", "asdasd"))
->withAndroidConfig(AndroidConfig::fromArray([
'priority' => 'high', // Use high priority
'ttl' => 86400 * 28, // 4 weeks in seconds
// 'notification' => [
// 'tag' => isset($data["type"]) && $data["type"] == "chat" && $data["action"] == "receiveMessage" ? strval($chat_message["id"]) : "1",
// 'sound' => 'default', // Ensure notification has sound
// 'channel_id' => 'high_importance', // Use the notification channel defined in your Android app
// ],
]))
->withApnsConfig(ApnsConfig::fromArray([
'headers' => [
'apns-collapse-id' => isset($data["type"]) && $data["type"] == "chat" && $data["action"] == "receiveMessage" ? strval($chat_message["id"]) : "1",
'apns-expiration' => strval(time() + 86400 * 28), // Expiry timestamp
'apns-priority' => '10',
],
'payload' => [
'aps' => [
// 'sound' => 'default',
"content-available" => 1,
"mutable-content" => 1
],
],
]));
} catch (Exception $e) {
return $e;
}
}
try {
$report = $messaging->sendAll($messages);
} catch (NotFound $e) {
return $e;
} catch (Exception $e) {
return $e;
}
return $report->successes()->count();
}
FCM 消息不是即时的或完全可靠的。 它们可以被推迟,也可以被放弃。 对于互联网上的任何消息传递技术都是如此。 它们往往相当快,但没有任何保证。
您不应该使用 FCM 消息的有效负载来使您的聊天保持最新状态。 您可以乐观地做到这一点,但您仍然应该以某种节奏(通常是在服务器打开消息应用程序时)对服务器进行 ping 操作,以获取错过的任何内容。 这不仅是 FCM 的经验法则,也是任何推送数据方式的经验法则。 例如,您永远不能依赖网络挂钩工作,并且应该始终有一个备份作业来提取该数据并处理任何遗漏。