GCM was working fine but now fcm do not recive any notification if it was sent by server it only work if o send from firebase console I am almost sure the problem is in array form i have in app:
String messageBody = remoteMessage.getNotification().getBody();
and in php:
$fields = array(
'registration_ids' => $this->devices,
'data' => array( "message" => $message ),
);
what do you think please
In your question you are sending a data-message, which is a message with a payload like:
{"registration_ids" : ["token1"], "data" : { "key1" : "value1"}}
To receive the data payload (in the example: key1:value1), the client app should to use:
String value1 = remoteMessage.getData().get("key1");
FCM also supports display-messages.
Example:
{"registration_ids" : ["token1"], "notification" : { "body" : "hello"}}
These messages are automatically displayed when the app is in background.
And they call onMessageReceived() only if the app is already open and in foreground.
In this second case you can access the field of the original notification via: remoteMessage.getNotification().getBody()
Display messages can also include a {"data" : { "key1" : "value1"}}.
If the app is in foreground it can access these values like a data-message.
If the app in bakground you need to wait until the user click the notification and starts an activity.
At that point you can access the data via: getIntent().getExtras()
PS: the notifications sent via Firebase Web Console are only display-messages.
Related
I an using FCM for sending a notification in my app and all work perfectly but when my app is in background then the notification is handle by android system notification tray
i want to handle my notification from myself i am sending this payload for send the notification
$fields = array(
'notification' => $notification,
'to' => '/topics/updates'
);
this will call my onMessageReceived when my app is in forground but when my app is in background this will not call my onMessageReceived the request is handled by system itself
i want to call my onMessageReceived when my app is in background
i am also try to remove notification key and only send data key like this
$fields = array(
'data' => $notification,
'to' => '/topics/updates'
);
but when i send the request from above field onMessageReceived is not called in both the condition in forground and background
i am try this in my xiaomi redmi note 4 (oreo) , redmi 4x(android 10) and android emulator(marshmello)
i am follow this ans for solve my problem but not work for me How to handle notification when app in background in Firebase
my FCM version is 17.3.4
and my android studio version is 3.5.3
If the data message is not received then the payload might be wrong. Here is my payload example (.js, but the structure should be pretty much the same):
const payload = {
data: {
title: finalTitle,
body: message,
icon: icon
},
topic: channel
};
admin.messaging().send(payload)
.then((response) => {
return
})
sorry for post this stupid questions FCM work in background when we post only data key not notification key
my mistake is this i wrap my notification builder by this
if (remoteMessage.getNotification() != null) {
// other code
}
I'm building android app with firebase cloud messaging.
My app can receive message from FCM console.
However, it cannot receive from python, although the response is good.
Could you give me some advice?
class fbMessaging():
def __init__(self):
cred = credentials.Certificate('./env/firebase.json')
firebase_admin.initialize_app(cred)
def send_to_device(self, text, token):
message = messaging.Message(
data = {
'title': 'test',
'body': text,
},
token = token,
)
response = messaging.send(message)
return response
def main():
fm = fbMessaging()
res = fm.send_to_device('test', 'MY CORRECT TOKEN')
print(res)
onMessageRecieved is here
override fun onMessageReceived(message: RemoteMessage?) {
val from = message!!.from
val data = message.data
Log.d(TAG, "from:" + from!!)
Log.d(TAG, "data:$data")
}
Printed response is below.
projects/match-XXXXX/messages/0:1554291593xxxxxx%43f99108f9xxxxxx
Using Firebase Cloud Messaging, you can send Notification payload or Data payload or both.
Notification Payload contains
title - Notification Title
body - Notification body
The key names fixed and can't be changed.
Data Payload, on the other hand, is simply a key-value pair and you can send any key name with string type as its value.
FCM Behavior:
Based on whether the app is in the foreground or background and the existence of Notification payload or Data payload or both, the FCM message is received by different components in the app.
Handling of FCM notification as per documentation,
Notification messages delivered when your app is in the background. In this case, the notification is delivered to the device’s system tray. A user tap on a notification opens the app launcher by default.
Messages with both notification and data payload, when received in the background. In this case, the notification is delivered to the device’s system tray, and the data payload is delivered in the extras of the intent of your launcher Activity.
This behavior has been explained clearly in the Receive Messages Section.
As you can see, if only in the case where Notification payload is sent in standalone you don't have to build Notification UI. Otherwise, you have create the Notification UI when onMessageReceived is called.
Using Python:
Notification Payload Example:
message = messaging.Message(
notification=messaging.Notification(
title='This is a Notification Title',
body='This is a Notification Body',
),
token=registration_token,
)
Data Payload Example:
message = messaging.Message(
data={
'score': '850',
'time': '2:45',
},
token=registration_token,
Both:
message = messaging.Message(
notification=messaging.Notification(
title='This is a Notification Title',
body='This is a Notification Body',
),
data={
'score': '850',
'time': '2:45',
},
token=registration_token,
I am sending data-message to my android application via FCM.But when I change the data payload structure,it does not seem to affect.
The FCM payload is
{
"to" : "eF3lccIdYs4:APA91bHpC1xWNl4MZXXXX",
"data" : {
"caller_name" : "Sobin Thomas",
"room" : "2000",
"call_type" : "audio"
},
"time_to_live" : 0
}
If I change it to
{
"to" : "eF3lccIdYs4:APA91bHpC1xWNl4MZXXXX",
"data" : {
"**caller**" : "Sobin Thomas",
"**room_number**" : "2000",
"call_type" : "audio",
**"call_time" : "2018-04-24 12:12:12",**
},
"time_to_live" : 0
}
Old data payload is still getting in the mobile app. And of course the data payload values change
Firebase Cloud Messaging will try to deliver every message, not just the last one. What's likely happening is that your device is receiving multiple messages in short succession, and only displays one.
If you want new messages to replace older message, you'll need to specify a so-called collapse_key. From the documentation:
This parameter identifies a group of messages (e.g., with collapse_key: "Updates Available") that can be collapsed, so that only the last message gets sent when delivery can be resumed. This is intended to avoid sending too many of the same messages when the device comes back online or becomes active.
I use Firebase Cloud Messaging (FCM) HTTP Legacy API protocol to send push notifications in JSON to android mobile devices. For the client side I use react-native-fcm library.
The aim is to send the notification to the particular devices when the application is in 3 states:
1) running
2) background running
3) killed
According to the documentation for FCM there are 3 different types of messages which can be sent via FCM service:
1) notification (has predefined fields)
2) data (set whatever fields you want)
3) mixed (notification + data).
The logic of listening the event for incoming message on the client side using react-native-fcm is the next:
this.notificationEmitterSubscription = FCM.on(FCMEvent.Notification, notif => {
if(notif && notif.fcm){
//received from Firebase
if(!notif.local_notification && notif.title){
let badge = parseInt(notif.badge);
FCM.setBadgeNumber(badge);
this.showNotification(notif.title, notif.body, badge);
}
//notification is clicked
if(notif.opened_from_tray){
FCM.setBadgeNumber(0);
this.executeNavigateAction(notif.fcm.action); //this method just navigates user to a particular screen in the application
}
}
});
Show notification method is implemented in this way:
showNotification(title, body, badge) {
FCM.presentLocalNotification({
body: body,
priority: "high",
title: title,
sound: "default",
large_icon: "ic_launcher",// Android only
icon: "ic_launcher",
show_in_foreground :true, /* notification when app is in foreground (local & remote)*/
vibrate: 300, /* Android only default: 300, no vibration if you pass null*/
lights: true, // Android only, LED blinking (default false)
badge: badge,
local: true,
click_action: NAV_SCREEN_NAME
});
}
notif.title, notif.body and notif.badge are the fields which are set in data section of the message when sending it via FCM API. In other word the message is sent in the (3) mixed form:
{
"registration_ids" : ["FCM_device_token_1", "FCM_device_token_2"],
"notification" :
{
"title" : "fcm notification message title",
"body" : "fcm notification message body",
"badge" : 111
},
"data" :
{
"title" : "fcm data message title",
"body" : "fcm data message body",
"badge" : 222
}
}
If the message is sent as (1) notification (without "data" section in the message, in this case some changes in the reading the fields are necessary, to change notif.title -> notif.fcm.title, but this is not the main point in the question) or mixed (3) then the listener for the notification is NOT triggered when application is (2) background running and (3) killed. As a result, the badge number is not set. BUT despite the fact that the method showNotification(title, body, badge) is not called (because the event listener is not triggered) the message IS shown. It seems that react-native-fcm has internal implementation for this situation to show (1) notification and (3) mixed messages automatically when application is not running. In other words, the listener IS called for (1) notification and (3) mixed messages only when the application is (1) running and IS NOT called when the application is in the (2) background or (3) killed and does NOT show the badge number. However, the message itself IS shown for all situations.
Another approach is to send a (2) data message. This type of FCM message triggers the listener (notificationEmitterSubscription) for all states of the application: (1) running and (2) background running and (3) killed. As a result, badge number is set in all these states. However, despite the fact that method showNotification(title, body, badge) is called whenever a data FCM message is received, method FCM.presentLocalNotification does NOT display the message if the application is killed.
Thus, in few words, I have a question.
How to:
EITHER display a badge number when (1) notification or (3) mixed message is received and the application is in (2) background running or (3) killed
OR display a (2) data message when the application is (3) killed?
Thank you!
The solution has been found. The statement is that: there is no code running if the application is killed, so the messages is handled and displayed out of your code. The message has to be set in the next format to be shown for the killed status:
{
"registration_ids" : ["FCM_token_1", "FCM_token_2"],
"data" :
{
"custom_notification" :
{
"title" : "FCM test title",
"body" : "FCM test body"
},
badge : 1
}
}
In your react-native application in the notification handler the notification is received as a json value of notif.custom_notification property. So, the code looks like this:
this.notificationEmitterSubscription = FCM.on(FCMEvent.Notification, notif => {
if(notif && notif.fcm){
//received from Firebase
if(!notif.local_notification && notif.custom_notification){
let message = JSON.parse(notif.custom_notification);
let body = message.body;
let title = message.title;
let badge = parseInt(notif.badge);
FCM.setBadgeNumber(badge);
this.showNotification(title, body, badge);
}
//notification is clicked
if(notif.opened_from_tray){
FCM.setBadgeNumber(0);
this.executeNavigateAction(notif.fcm.action);
}
}
});
The issue can be solved as a resolved one.
I am using a phonegap-plugin-push for receiving notifications in Cordova Application. I am deploying on android Marsh-mellow for testing.
I want to see and store the contents of the Notifications received through Firebase Console when the app is in background.
Here is my Code -
document.addEventListener("deviceready",onDeviceReady,false);
function onDeviceReady(){
var push = PushNotification.init({ "android": {"senderID": "91254247XXXX"}});
push.on('registration', function(data) {
console.log(data.registrationId);
//document.getElementById("gcm_id").innerHTML = data.registrationId;
});
push.on('notification', function(data) {
alert("On Notification function!!");
// data.message,
// data.title,
// data.count,
// data.sound,
// data.image,
// data.additionalData
console.log("notification event");
console.log(JSON.stringify(data));
alert(JSON.stringify(data));
//Do something
});
push.on('error', function(e) {
alert(e);
});
}
When the app is in foreground (on screen) I receive the contents (title, message, data, etc.) properly and I am able to see them in alert box directly in the app.
But when app is in background (not on screen but running in backround), I get the notification in Notification Area. When I click on the notification received, it is redirecting me to the last opened page in the app.
The function push.on('notification', function(data) {} is not called. No alert messages are shown. Can someone help me how to access the notification message and data?
I found the answer after 2 days of research. We have to set "content-available" to 1 in the data field. Else it wont call on notification block if app is in background.
And this is not possible as of now through Google Firebase Console.
We have to send our custom payload messages (data or notification or both) seperately using any one of the firebase servers.
Detailed info can be found on the plugin's GitHub Page on background notifications.
I used NodeJs firebase-admin. I followed these setup guidelines and these steps for sending messages and it worked for me.
Here is my working code (NodeJS) -
var admin = require("firebase-admin");
var serviceAccount = require("pushnotificationapp-xxxxx.json"); //this is the service account details generated from server
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://pushnotificationappxxxxx.firebaseio.com/" //your database URL here.
});
var registrationToken = "eYjYT0_r8Hg:APA91bG0BqWbT7XXXXX....."; //registration token of the device
var payload ={
"data": {
"title": 'Test Push',
"message": 'Push number 1',
"info": 'super secret info',
"content-available": '1' //FOR CALLING ON NOTIFACATION FUNCTION EVEN IF THE APP IS IN BACKGROUND
}
};
//send the notification or message
admin.messaging().sendToDevice(registrationToken, payload)
.then(function(response) {
console.log("Successfully sent message:", response);
})
.catch(function(error) {
console.log("Error sending message:", error);
});
UPDATE :
I implemented the same using php server too.
Here is my working php code for sending notifications using HTTP POST to FCM server-
<?php
$url = 'https://fcm.googleapis.com/fcm/send';
$data =
array(
"to" => "eYjYT0_r8Hg:APA91bG0BqWbT7XXXXX.....",
"data" => array(
"title"=> 'Test Push',
"message"=> 'Push number 1',
"info"=> 'super secret info',
"content-available"=> '1')
);
// use key 'http' even if you send the request to https://...
$options = array(
'http' => array(
'header' => array("Content-Type:application/json",
"Authorization:key=AAAA1HfFM64:APA91XXXX...."), //this is the server authorization key from project settings tab in your Firebase Project
'method' => 'POST',
'content' => json_encode($data)
)
);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
if ($result === FALSE) { echo "Caught an error"; }
else{
echo $result;
}
?>
i was going through the same issue but i added "content-available": '1' also but my phone was not receiving any background push.
Finally i found that it was issue with my phone as mentioned here: https://github.com/phonegap/phonegap-plugin-push/blob/master/docs/PAYLOAD.md#huawei-and-xiaomi-phones
Huawei and Xiaomi Phones
These phones have a particular quirk that when the app is force closed that you will no longer be able to receive notifications until the app is restarted. In order for you to receive background notifications:
On your Huawei device go to Settings > Protected apps > check "My App" where.
On your Xiaomi make sure your phone has the "Auto-start" property enabled for your app.
On your Asus make sure your phone has the "Auto-start" property enabled for your app.
Hope it will help someone.