I am building a chat part in my flutter app. I was pushing my notifications as Notifications
and not as only-data messages
using FCM service. I faced a problem of firebase collapsing notifications if the user wasn't online, where it will only push the last notification, but I was relying on the notifications for payload to update the chats and chat messages. I had to change to only-data messages to avoid the collapsing issue. it was wroking in debug mode when the app was in foreground and background on both Android
and iOS
. I wanted to test if the app was terminated, and I found that the data messages will not be received until the user opens the app, whether the app was in background or terminated. While if I use normal notifications, it would always be received. Can someone help me understand and solve this issue ?
Laravel FCM function:
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();
}
EDIT
I tried re-running the app in profile
mode and it worked just fine. seems like it's a flutter release mode problem. I don't know if release mode behaviour is the one that will happen if uploaded to app store and play store. I'll try and update soon.
The problem specific to not receiving data messages was not because of Firebase but becauses of the background handler as it didn't have @pragma('vm:entry-point')
so that Flutter doesn't remove the function when shaking down when trying to run in release as descibed in Firebase receive message documentation