I can succesfully send Firebase cloud messages to my Android sample project. As described in here, I apply step 2 and it works so far.
My JSON body:
{
"to": "/topics/testTopic",
"data": {
"key1" : "val1",
"key2" : true
}
}
has a data field which I can access properly in my onMessageReceived() method:
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
String toVal = remoteMessage.getTo();
Map<String, String> data = remoteMessage.getData();
}
But the getTo() method gets null.
How can I access the 'to' field in my originating JSON?
I was expecting to have "/topics/testTopic" in im variable toVal.
I think you're looking for RemoteMessage.getFrom():
Get the sender of this message.
This will be the sender ID or the topic for topic messages.
Related
I am developing an Android application in which I would like to receive push notification by FCM.
The onMessageReceived callback is triggered but the RemoteMessage.getData() has returned null value and when I evaluated the expression , the RemoteMessage.mBundle has the required data but not in JSON format
The following is the data I am getting from RemoteMessage.mBundle
Bundle[{google.sent_time=1519016906113, gcm.notification.categoryId=80302, google.ttl=2419200, gcm.notification.notificationId=127647, gcm.notification.e=1, gcm.notification.threadId=127093, gcm.notification.title=Moni Expert has commented on your post, from=612005318045, gcm.notification.roleId=115442, gcm.notification.userId=76284, gcm.notification.profileUrl=/image/user_male_portrait?img_id=122306&img_id_token=%2B99KTi28KTf7%2BehhVakxUyPqAuU%3D&t=1519016037919, google.message_id=0:1519016906118429%c05b1316c05b1316, gcm.notification.lastName=Expert, gcm.notification.notificationDate=2018-02-19 05:07:17.821, gcm.notification.timeStamp=Fri Feb 16 14:57:08 GMT 2018, gcm.notification.body=Moni Expert has commented on your post, gcm.notification.flag=0, gcm.notification.type=1, gcm.notification.firstName=Moni, gcm.notification.threadStatus=Published, gcm.notification.subject=posted, gcm.notification.roleName=D4E Admin, gcm.notification.userName=moniexpert, gcm.notification.postedUserId=76284, collapse_key=digital.engineers.club, gcm.notification.notification=Moni Expert has commented on your post}]
I have searched a lot to convert this data to Json format but nothing helped.
Update :
The code snippet has mentioned below
public class D4EPushService extends FirebaseMessagingService {
private static final String TAG = "MyFMService";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// Handle data payload of FCM messages.
Log.d(TAG, "FCM Message Id: " + remoteMessage.getMessageId());
Log.d(TAG, "FCM Notification Message: " +
remoteMessage.getNotification());
Log.d(TAG, "FCM Data Message: " + remoteMessage.getData());
remoteMessage.mBundle;
}
I am not able to even assign remoteMessage.mBundle to new bundle variable in my code snippet as it has privately declared in RemoteMessage class
Please anyone help me to find the solution.
Try below solution it is work for me.
if (remoteMessage.getData().size() > 0) {
Map<String, String> data = remoteMessage.getData();
String message = data.get("your key");}
I'm having difficulty in passing background data to a screen. In the background the app is calling the screen correctly but the data that this screen needs that is in the "data" (id from data object) in the notification is not being picked up.
In foreground I got "data" correctly.
notification json
{
"to" : "akshih890uhnkjh389jfkn3...",
"priority" : "normal",
"time_to_live" : 0,
"data" : {
"type" : "my_type",
"id" : "my_id"
},
"notification" : {
"body" : "Test body",
"title" : "Test title",
"click_action" : ".MyActivity"
}
}
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
String title = remoteMessage.getNotification().getTitle();
String body = remoteMessage.getNotification().getBody();
String clickAction = remoteMessage.getNotification().getClickAction();
Map<String, String> data = remoteMessage.getData();
Gson gson = new Gson();
MyObject myObject = new MyObject(data.get("id"), data.get("type"), remoteMessage.getNotification().getTitle(),
remoteMessage.getNotification().getBody());
Intent intent = new Intent(myObject.getClickAction());
intent.putExtra("id", myObject.getId());
PendingIntent contentIntent = PendingIntent.getActivity(
this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
sendFCMNotification(title, body, contentIntent);
}
MyActivity
if(getIntent() != null) {
Bundle extras = getIntent().getExtras();
code = extras.getString("id");
}
int id = Integer.valueOf(remoteMessage.getData().get("id"));
Since you use remoteMessage.getData(), you get entire data object, not an object who has data json inside, you get actual data json with your fields.
String data = remoteMessage.getData();
Gson gson = new Gson();
MyObject myObject = gson.fromJson(data, MyObject.class);
If your app is in background, Firebase will not trigger onMessageReceived(). Why.....? I have no idea. In this situation, I do not see any point in implementing FirebaseMessagingService.
According to docs, if you want to process background message arrival, you have to send 'click_action' with your message. But it is not possible if you send message from Firebase console, only via Firebase API. It means you will have to build your own "console" in order to enable marketing people to use it. So, this makes Firebase console also quite useless!
There is really good, promising, idea behind this new tool, but executed badly.
I suppose we will have to wait for new versions and improvements/fixes!
in the background, you can get data from intent extras if you want to call specific activity then specify it in click_action attribute of data
refer:
Firebase Server reference
Firebase Push
I found the problem, when the server sends me the notification object in the background I can not see the date. But when the server sends only the date I get the id however how will I be able to build a notification without the title and body data?
I have a problem regarding my SNS Push Notifications. I have the following lambda code:
db.scan(params, function(err, data) {
if (err) {
console.log(err); // an error occurred
}
else {
data.Items.forEach(function(record) {
var receiverID = record.userDeviceToken.S;
var message = "You have a new invitation to the event";
var topic = "Friend's invitation";
var eventText = JSON.stringify(event);
console.log("Received event:", eventText);
var sns = new AWS.SNS();
var params = {
Message: message,
Subject: "Friend's invitation",
TargetArn: receiverID,
};
sns.publish(params, function(err, data) {
if (err) {
console.log('Failed to publish SNS message');
context.fail(err);
}
else {
console.log('SNS message published successfully');
context.succeed(data);
}
});
});
//context.succeed(data.Items); // data.Items
}
});
};
Now my goal is to get the "Subject" or "topic" sometimes, if it is possible. I cannot find it in documentation, and I need it to customize my notification title depending on the push message sent (I have few functions).
When I used sample amazon app I found this cound in Push Listener Service:
public static String getMessage(Bundle data) {
// If a push notification is sent as plain text, then the message appears in "default".
// Otherwise it's in the "message" for JSON format.
return data.containsKey("default") ? data.getString("default") : data.getString(
"message", "");
}
This works, but the "data" itself has the following data:
Bundle[{google.sent_time=1480364966070, google.message_id=0:1480364966079787%22269524f9fd7ecd, default=You have a new invitation to the event, collapse_key=do_not_collapse}]
Therefore, it is just providing some internal data and the "message" itself. I cannot access the topic.
My question is: how to get other variables in the Android code so I can use them further on? Can I add custom variables by myself through data bundle?
I have notifications in JSON format. I just wonder, whether the only way is to put the data I want in JSON format inside the message, and then read the message accordingly, or maybe I can attach the required data from lambda function to the push notification already?
I am new to Firebase and the main reason I adapted to it from my old MySql DB is the ability to send push notification and dynamic links. I have been trying for the past two days to send notification to a group of people who have subscribed to a topic from my node.js script. The script always returns InternalServerError. I am able to send notification from the Firebase console but that is not good enough for my app as I need to implement dynamic notification (i.e. triggered by one users action).
So far I did not understand what was in the official docs and tried following a tutorial I found and I am currently here
app.get('/push',function(req,res){
/*var title = req.params.title;
var body = req.params.body;*/
// var confName = req.params.name;
var message = { //this may vary according to the message type (single recipient, multicast, topic, et cetera)
to: '/topics/ilisten',
// collapse_key: 'your_collapse_key',
notification: {
title: 'This is Title',
body: 'This is body'
},
data: { //you can send only notification or only data(or include both)
my_key: 'Conf Name here'
}
};
fcm.send(message, function(err, response){
if (err) {
console.log("Something has gone wrong!"+err);
} else {
console.log("Successfully sent with response: ", response);
}
});
})
My first question is what should I do in the to field so that all the users in my app reciece the notification.
I would also like to take a look at correct and complete implementation of this concept with android code. If anyone has such code please share it here as it would help the future Firebase users who cannot understand the official docs like me.
Following is one approach using node-gcm (https://github.com/ToothlessGear/node-gcm)
var gcm = require('node-gcm');
var sender = new gcm.Sender(<sender_key>);
var message = new gcm.Message();
message.addNotification('title', title);
message.addNotification('body', body);
sender.send(message, { topic: "/topics/" + topic }, function (err, response) {
if (err) console.error(err);
else console.log(response);
});
my addAsyncStanzaListner is being called when an ack message is received from Firebase Cloud Messaging services. I need to ack this messages according to the docs. The problem that I am having is I can't reach the "message_type" "key"/"value" pair inside the JSON object that arrives inside the message stanza that's received. Could you please help me in accessing this important value/pair. I am using Smack Library 4.1. I've been following this post answer for this setup, but somehow It doesn't work:
GCM XMPP Server using Smack 4.1.0
Here's how the code is looking like:
other_connection.addAsyncStanzaListener(new StanzaListener() {
#Override
public void processPacket(Stanza packet) throws SmackException.NotConnectedException {
//how should i convert this stanza into a message stanza
//I have tried Message message = (Message)packet; IT DOESNT WORK
//I have tried getting the extension with the GCM Namespace. It doesnt
//return a json string
In your code you just recive a Stanza as Java Object.
Stanza has a method to output an XML.
You can use this method to obtain a JSON if you need, just add some custom functionality.
Following this example
your code can looks like this:
#Override
public void processPacket(Stanza packet) throws SmackException.NotConnectedException {
JSONObject jsonObj = XML.toJSONObject(packet.toXML());
String json = jsonObj.toString();
//foo
Note: This answer is for the general problem of extracting JSON from a message. In the case of FCM, it's possible that there's another method that's more appropriate.
Suppose your have a Stanza object that corresponds to the following XML:
<message from='a#example.com' to='b#example.com' type='normal'>
<json xmlns='urn:xmpp:json:0'>{ "key1" : "value1", "key2": "value2" }</json>
<body/>
</message>
To extract the JSON string, you need to do:
import org.jivesoftware.smackx.json.packet.JsonPacketExtension;
...
JsonPacketExtension jsonPacketExtension = JsonPacketExtension.from(stanza);
String contentJson = jsonPacketExtension.getJson();