Firebase RemoteMessage has filled Bundle but getData() is empty - android

My firbase RemoteMessage has a mBundle with 12 key value pairs, according to debugger, those field were filled .
But when I say: remoteMessage.getData(); the resulting ArrayMap Map<String, String> has size 0 and thus no elements.
How can I access the Map of remoteMessage?

I know this might be late but You can get the data from Notification Object in RemoteMessage
String title = remoteMessage.getNotification().getTitle();
String body = remoteMessage.getNotification().getBody();
hope this helps

I also encountered same problem.
And finally fixed this problem.
In my case, server side's sending FCM payload problem.
like this.
options = {
priority: 'high',
notification: {
title: "title",
body: "message",
url: "some_url",
image_url: "some_image_url"
}
And I updated like following,
options = {
priority: 'high',
notification: {
title: "title",
body: "message",
},
data: {
url: "some_url",
image_url: "some_image_url"
}
After that, I could get payload values by remoteMessage.getData().

The debugger initially showed the data field as empty, but calling getData() returned the result, and the debugger then showed the correct map.

Related

How to get NotificationActionButton input data with flutter?

I'm trying to get notification action button data. That is when the user fill the input action, I get the data he entered.
Just like this.
I am using the awesome_notifcations flutter package.
This is my function to that creates new notification with input action for comment
Future<void> create({
required String key,
required String title,
required String body,
required String bigPicture,
}) async {
await _notiff.createNotification(
content: NotificationContent(
id: DateTime.now().millisecondsSinceEpoch.remainder(10),
channelKey: key,
title: title,
body: body,
bigPicture: bigPicture,
notificationLayout: NotificationLayout.BigPicture,
),
actionButtons: [
NotificationActionButton(
buttonType: ActionButtonType.InputField,
enabled: true,
label: "Comment",
key: "COMMENT_BUTTON_KEY")
]);
}
Here I just want to get the user's comment.
How to do so ?
Do you need create listener to get new notifications like this:
AwesomeNotifications().actionStream.listen(
(ReceivedNotification receivedNotification){
Navigator.of(context).pushNamed(
'/NotificationPage',
arguments: {
// your page params. I recommend you to pass the
// entire *receivedNotification* object
id: receivedNotification.id
}
);
}
);
PD: Do you need replace with your data, this information is in docs (5. How to show Local Notifications)

How to send simple "push notification" from one device to other device?

I have an application that I made with Flutter. I am trying to write a method for users to add each other as friends in my application, but before I do this, I want to send push notifications from one device to the other. Actually, I think if I start, I can solve the rest with my own algorithm.
Ways I've tried:
installed node.js
from project terminal: firebase login
firebase init
functions file created and exists in my project
i have index.ts file
I get unique token for each device when app opened.
I want to put a simple notification sending code in the index.ts file, but I couldn't. And this notification should work from one device to another.
Here is simple solution to send device to device notification.
First create json formatted parameters like below
var params = {
"to": "device token",
"notification": {
"title": "Notification Title",
"body": "Notification Message",
"sound": "default",
},
"data": {
"customId": "01",
"badge": 0,
"alert": "Alert"
}
};
Then var url = 'https://fcm.googleapis.com/fcm/send'; call as api.
Get response like below code
var response = await http.post(url,
headers: {
"Authorization": "key= Web server Key over here",
"Content-Type": "application/json"
},body: json.encode(params)
);
if (response.statusCode == 200) {
Map<String, dynamic> map = json.decode(response.body);
print("fcm.google: "+map.toString());
}
else {
Map<String, dynamic> error = jsonDecode(response.body);
print("fcm.google: "+error.toString());
}

Error: "data must only contain string values" firebase cloud messaging

I'm trying to send some data from my node.js server to an android client via FCM(Firebase Cloud Messaging). I get the following error: "data must only contain string values" when sending it. My data contains 2 JSONObjects. Do I have to convert them to strings or what is the way to go here? Thanks.
var message = {
notification:{
"title": "Alert!",
"body": position[0] + " has left Area: " + activeGeofences[i][1].name
},
data:{
Geofence: activeGeofences[i][1],
Position: position[1]
},
token: activeGeofences[i][0]
};
To convert any JSON objects to a string, you can use JSON.stringify(). On the receiving side you can then use JSON.parse() (or your platform's equivalent) to parse the string back into a tree structure.
You can also do this, since it seemed more accurate to me
data: {
key1: "value1",
key2: "value2",
}
you just have to make sure that value1 or value2 or any n key's value pair is string if its a int or anything else it would throw the error. This could save you from parsing thing.
Inside data object data type should be always strings.
If you will pass type a number data type an error will occur.
let message = {
notification: {
title: payload.title,
body: payload.message,
},
data: {
name: 'sds',
type: '2',
_id: 'sdsd',
},
token: deviceToken,
};

Firebase Functions receive Object instead of String

Bear with me. I've spent a month just PHRASING this question: I've been using Firebase Database and Firebase functions for about a year. I've gotten it to work... but only if I sent the text of the message as a STRING. The problem is that now I wish to receive an OBJECT instead but I'm unsure of how to do this in FireBaseMessage.
My previous structure:
messages
T9Vh5cvUcbqC8IEZowBpJC3
ZWfn7876876ZGJeSNBbCpPmkm1
message
"messages": {
".read": true,
"$receiverUid": {
"$senderUid": {
"$message": {
".read": true,
".write": "auth.uid === $senderUid"
And my function for the listener was this:
exports.sendMessage = functions.database.ref('/messages/{receiverUid}/{senderUid}/{message}')
This is problematic... for a variety of reasons. Namely if the old message was "Hey" and then that same person just writes "Hey" again... then the original gets overwritten.
So my NEW structure is more like this:
messages
-LkVcYqJoEroWpkXZnqr
body: "genius grant"
createdat: 1563915599253
name: "hatemustdie"
receiverUid: "TW8289372984KJjkhdsjkhad"
senderUid: "yBNbs9823789KJkjahsdjkas"
Which is written as:
mDatabase.child("messages").push().setValue(message);
...and I'm just unsure about how to write out that function.
I mean... IDEALLY... it would be something like:
exports.sendMessage = functions.database.ref('/messages/{receiverUid}/{senderUid}/{msgID}/{msgOBJECT}')
...but I'm just not sure how Firebase functions is reading this new structure.
Now I'm pushing to the database like so:
mDatabase.child("messages").child(guid).child(user_Id).push().setValue(msgObject).addOnSuccessListener(this, new OnSuccessListener<Void>() {
#Override
public void onSuccess(#NonNull Void T) {
Log.d("MessageActivity", "Message Sent");
Basically I would just like to receive the message object... with everything in it... when it arrives from the notification... and be able to easily parse the body, date, userids, etc.
Can someone explain the correct way to go about this?
UPATE By request here's the complete cloud function:
exports.sendMessage = functions.database.ref('/messages/{receiverUid}/{senderUid}/{msgId}/{message}')
.onWrite(async (change, context) => {
const message = context.params.message;
// const messageId = context.params.messageId;
const receiverUid = context.params.receiverUid;
const senderUid = context.params.senderUid;
// If un-follow we exit the function.
if (!change.after.val()) {
return console.log('Sender ', senderUid, 'receiver ', receiverUid, 'message ', message);
}
console.log('We have a new message: ', message, 'for: ', receiverUid);
// Get the list of device notification tokens.
const getDeviceTokensPromise = admin.database()
.ref(`/users/${receiverUid}/notificationTokens`).once('value');
// Get the follower profile.
const getSenderProfilePromise = admin.auth().getUser(senderUid);
// The snapshot to the user's tokens.
let tokensSnapshot;
// The array containing all the user's tokens.
let tokens;
const results = await Promise.all([getDeviceTokensPromise, getSenderProfilePromise]);
tokensSnapshot = results[0];
const sender = results[1];
// Check if there are any device tokens.
if (!tokensSnapshot.hasChildren()) {
return console.log('There are no notification tokens to send to.');
}
console.log('There are', tokensSnapshot.numChildren(), 'tokens to send notifications to.');
console.log('Fetched sender profile', sender);
// console.log('David you're looking for the following UID:', followerUid);
// Notification details.
const payload = {
notification: {
title: `${sender.displayName} sent you a message.`,
body: message,
tag: senderUid
},
// 'data': { 'fuid': followerUid }
data: {
type: 'message',
name: sender.displayName
}
};
console.log('David you are looking for the following message:', message);
// Listing all tokens as an array.
tokens = Object.keys(tokensSnapshot.val());
// Send notifications to all tokens.
const response = await admin.messaging().sendToDevice(tokens, payload);
// For each message check if there was an error.
const tokensToRemove = [];
response.results.forEach((result, index) => {
const error = result.error;
if (error) {
console.error('Failure sending notification to', tokens[index], error);
// Cleanup the tokens who are not registered anymore.
if (error.code === 'messaging/invalid-registration-token' ||
error.code === 'messaging/registration-token-not-registered') {
tokensToRemove.push(tokensSnapshot.ref.child(tokens[index]).remove());
}
}
});
return Promise.all(tokensToRemove);
});
Since you now store the sender and receiver's UIDs inside the message, the declaration of your Cloud Function will need to change.
Instead of this:
exports.sendMessage = functions.database.ref('/messages/{receiverUid}/{senderUid}/{msgId}/{message}').onWrite(async (change, context) => {
You'll need to trigger on:
exports.sendMessage = functions.database.ref('/messages/{messageId}').onWrite(async (change, context) => {
So with this change your code will trigger on each message that is written /messages.
Now you "just" need to get the sender and receiver's UID. And since you no longer can get them from the context, you will instead get them from the change. Specifically change.after contains the data snapshot as it exists in the database after the write has completed. So (as long as you're not deleting the data), you can get the UIDs with:
const receiverUid = change.after.val().receiverUid;
const senderUid = change.after.val().senderUid;
And you'll also get the actual message from there of course:
const message = change.after.val().message;
And just in case you need the message ID (the -L... key that it was written under in the database):
const messageId = change.after.val().messageId;
You need a trigger on just the messageId:
exports.sendMessage = functions.database.ref('/messages/{messageId}').onWrite((change, context) => {
const changedData = change.after.val(); // This will have the complete changed data
const message = change.after.val().message; // This will contain the message value
......
});
Elaborating on Frank's answer:
You can't get the data from context like const message = context.params.message;because those parameters don't exists anymore on the context.

Push notification to Android from Rails api using FCM is not sending the notification?

i am coding an Api Rest in rails 5, using gem 'fcm' to send notifications. I have already configure firebase in my android app and I can send notifications successfully from the Firebase console, but from my rails api i cannot receive the notificacion in my device, this is my code:
this is my rails controller:
class AccionesController < ApplicationController
def enviar
require 'fcm'
fcm = FCM.new("AAAAlBfTsV4:AheregoesmySERVEKEYsXXm-vQGfMjVuo8TpYrApHsnGU4ZasdfajsdfñalUtf26LeND4U4lXFZZplpzJjTWoiisWP-Esl5afCSTmiDI9y5gP6OObqY76NVcOn9ceaIUGMZ")
# fcm = FCM.new("my_server_key", timeout: 3)
registration_ids= [params[:devicetoken]] # an array of one or more client registration tokens
options = {data: {score: "mynewscore"},
notification: {
title: "Message Title",
body: "Hi, Worked perfectly",
icon: "myicon"}
,collapse_key: "testeando desde rails", priority: "high"}
response = fcm.send(registration_ids, options)
render json: response
end
def noti_params
params.permit(:devicetoken)
end
end
I execute from Postman this is the route that execute the controller:
http://localhost:3000/acciones/enviar?here goes the device token as parameter
And, here is the response:
{"body":"{\"multicast_id\":5276983113254623155,\"success\":1,\"failure\":0,\"canonical_ids\":0,\"results\":[{\"message_id\":\"0:1502991819420287%2293308c2293308c\"}]}","headers":{"content-type":["application/json;
charset=UTF-8"],"date":["Thu, 17 Aug 2017 17:43:39
GMT"],"expires":["Thu, 17 Aug 2017 17:43:39
GMT"],"cache-control":["private,
max-age=0"],"x-content-type-options":["nosniff"],"x-frame-options":["SAMEORIGIN"],"x-xss-protection":["1;
mode=block"],"server":["GSE"],"alt-svc":["quic=\":443\"; ma=2592000;
v=\"39,38,37,35\""],"accept-ranges":["none"],"vary":["Accept-Encoding"],"connection":["close"]},"status_code":200,"response":"success","canonical_ids":[],"not_registered_ids":[]}
the response shows success: 1 and status code: 200 but the notification never reaches the device,and the firebase console does not show the message.
Am I missing something?
please help?
or is there another way or ruby gem to send notification with a clear example?
any suggestions are welcome... thanks in advance
Instead of using fcm gem, you can also use RestClient gem. The usage for fcm notifications is as follow.One thing to note is if the payload is passing using ".to_json", the header content type also must be specified as json. Hope this help.
def self.send_noti(device_token)
options = data().merge ({"to": "#{device_token}"})
RestClient.post("https://fcm.googleapis.com/fcm/send", options.to_json, headers={'Content-Type' => 'application/json','Authorization' => "key=#{ENV['fcm_token']}"})
end
def self.data()
options = {
"notification": {
"body": "Your noti body",
"title": "Your noti title"
},
"data": {
"d1": "Your data" #can be any, d1, status or whatever
}
}
end
rest-client gem
fcm_client = FCM.new(your_firebase_key)
registration_ids= [user_device_token]
options = {
priority: 'high',
data: {
message: "Hai",
location: location
},
notification: {
body: "Hai",
location: "location",
sound: 'default'
}
}
fcm_client.send(registration_ids, options)
end
end
try this message options because the error should be your notification syntax.
options = {
priority: 'high',
data: {
message: "Hai",
location: location
},
notification: {
body: "Hai",
location: "location",
sound: 'default'
}
}

Categories

Resources