I have an Android app which calls a web service to send messages to us for support.
There is a website which we develop where we can respond to a message and we use Firebase for that. Up until now we were just sending a title and a message like so:
var applicationID = "snip";
var senderId = "snip";
WebRequest tRequest = WebRequest.Create("https://fcm.googleapis.com/fcm/send");
tRequest.Method = "post";
tRequest.ContentType = "application/json";
var data = new
{
to = model.RequestFirebaseID,
notification = new
{
body = model.ResponseMessage,
title = model.ResponseTitle
}
};
In the Android app I am able to extract the message title using the following Java code
String notificationTitle = remoteMessage.getNotification().getTitle();
String notificationBody = remoteMessage.getNotification().getBody();
However now I am trying to send back a custom field called id,so I amend the code to be
var data = new
{
to = model.RequestFirebaseID,
notification = new
{
body = model.ResponseMessage,
title = model.ResponseTitle,
requestid = model.id
}
};
So now when I send a message back to the device using Firebase I have this code to try and read the id field.
String messageID = remoteMessage.getData().get("requestid");
However this causes ends up as null.
So I have tried testing sending this via the Firebase console, I add requestid to the custom data section and give it a value and the above code is able to read it.
It seems that when I am sending via the web application it cannot see the requestid field.
You have to include the data message inside the payload. Something like this:
var payload = new
{
to = model.RequestFirebaseID,
notification = new
{
body = model.ResponseMessage,
title = model.ResponseTitle
},
data = new
{
requestid = model.id
}
};
I changed the root variable name to payload to distinguish it.
If you add a custom data when using the Firebase Notifications console to send the message, it is included inside a data message parameter instead of the notification message. See the Message Types documentation for the difference of the two.
Related
I'm writing VB.NET code to send notification to android Emulator. I can successfully send test message from the firebase control. However, it failed when I tried to send message via VB.NET code in my local machine and get error "The remote server returned an error: (401) Unauthorized".
I have tried looking at the following link:
FCM (Firebase Cloud Messaging) Push Notification with Asp.Net
and following the instructions but it still not working.
Here is my code:
Imports System.Net
Imports Newtonsoft.Json
Public Class Notification
Public Sub SendNotification(ByVal deviceIDList As List(Of String), ByVal title As String, ByVal bodyMsg As String)
Dim fcmPath As String = "https://fcm.googleapis.com/fcm/send"
Dim serverKey As String = "AIzaxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxoCAeI"
Dim senderID As String = "35xxxxxxx37"
Dim request As HttpWebRequest = CType(HttpWebRequest.Create(fcmPath), HttpWebRequest)
With request
.Method = "POST"
.ContentType = "application/json"
.Headers.Add(String.Format("Authorization: key={0}", serverKey))
.Headers.Add(String.Format("Sender: id={0}", senderID))
End With
Using streamWriter = New StreamWriter(request.GetRequestStream())
Dim webObject As New WebRequestFcmData
With webObject
.registration_ids = deviceIDList
.notification.title = title
.notification.body = bodyMsg
.notification.content_available = True
.notification.sound = "default"
.notification.priority = "high"
End With
Dim body = JsonConvert.SerializeObject(webObject)
With streamWriter
.Write(body)
.Flush()
.Close()
End With
End Using
Dim httpResponse = CType(request.GetResponse(), HttpWebResponse)
Using streamReader As New StreamReader(httpResponse.GetResponseStream)
Dim result = streamReader.ReadToEnd
End Using
End Sub
End Class
Public Class WebRequestFcmData
Public Property registration_ids As List(Of String)
Public Property notification As New NotificationData
End Class
Public Class NotificationData
Public Property body As String
Public Property content_available As Boolean
Public Property priority As String
Public Property title As String
Public Property sound As String
End Class
The error occurred at the line:
Dim httpResponse = CType(request.GetResponse(), HttpWebResponse)
Here is the server key and sender ID that I use:
Updated:
I tried sending web request from Postman application and it also gave the same error (401: Unauthorized) as shown in the figure below:
OK. I made a silly mistake by using API Key which is not actual Server key. Even though I have read that I should go to cloud messaging tab in project setting, I misunderstood that I have to look in cloud messaging tab in the side bar which is wrong. Here is the step where I found server key:
Click on the setting button near Project Overview
Choose the first option (Project setting)
Click on the second tab (Cloud messaging)
Use the server key and sender ID in this page
At first, I tried looking for server key in cloud messaging tab in the sidebar which is wrong location.
In my app, i couldn't parse the "payload" object coming from push notification. There is automatically added '/' in each property in payload after push sent from server. How can i parse the payload property/object and get the notification data in my code?
Here is the payload object :
"payload":"{\"android\":{\"badge\":\"2\",\"alert\":\"Microfinaa_new_ne\",\"sound\":\"door_bell\",\"icon\":\"little_star\",\"vibrate\":true,\"title\":\"Mahboob Zaman\"}}"
And here is the full notification message coming from fcm server:
{"type":"callback","source":{"showTrayNotification":true,"pushType":"gcm","enabled":false,"showTrayNotificationsWhenFocused":false,"singleCallback":false,"focusAppOnPush":false,"showAppOnTrayClick":true,"debug":false,"apiName":"Ti.Module","bubbleParent":true,"invocationAPIs":[],"__propertiesDefined__":true,"_events":{"callback":{}}},"payload":"{\"android\":{\"badge\":\"2\",\"alert\":\"Microfinaa_new_ne\",\"sound\":\"door_bell\",\"icon\":\"little_star\",\"vibrate\":true,\"title\":\"Mahboob Zaman\"}}","bubbles":false,"cancelBubble":false}
And here is my code -
CloudPush.addEventListener('callback', function(evt) {
var json = JSON.stringify(evt.payload);
Ti.API.info("datos = " + json.android);// This line shows undefined
});
Payload is already string you need to parse it and use inverse function
var json = JSON.stringify(evt.payload);
JSON.stringify(Object) -> return String
JSON.parse(StringOject) -> return Object
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 am trying to register my Android device to receive push notifications, however the amazon server is returning an error saying it cannot find my PlatformApplicationArn. I am setting it using their sdk but it seems not to be finding it.
This is the error:
AWS Error Message: Invalid parameter: PlatformApplicationArn Reason: no value for required parameter
This is the code that sends it:
String platformApplicationArn = "arn:aws:sns:us-east-1:897955111111:app/GCM/com.myapp";
AWSCredentials awsCredentials = new BasicAWSCredentials("XXXXXXXX", "XXXXXXXXXXXXXXXXXXXXX");
pushClient = new AmazonSNSClient(awsCredentials);
CreatePlatformEndpointRequest createPlatformEndpointRequest = new CreatePlatformEndpointRequest();
String customPushData = "my custom data";
CreatePlatformEndpointRequest platformEndpointRequest = new CreatePlatformEndpointRequest();
platformEndpointRequest.setCustomUserData(customPushData);
platformEndpointRequest.setToken(pushNotificationRegId);
platformEndpointRequest.setPlatformApplicationArn(platformApplicationArn);
CreatePlatformEndpointResult result = pushClient.createPlatformEndpoint(createPlatformEndpointRequest);
You have 2 instances CreatePlatformEndpointRequest and you're setting the token and applicationArn on one but using the other for your SNSClient request so it's missing the required parameters.
String platformApplicationArn = "arn:aws:sns:us-east-1:897955111111:app/GCM/com.myapp";
AWSCredentials awsCredentials = new BasicAWSCredentials("XXXXXXXX", "XXXXXXXXXXXXXXXXXXXXX");
AmazonSNSClient pushClient = new AmazonSNSClient(awsCredentials);
//probably no need for this
String customPushData = "my custom data";
CreatePlatformEndpointRequest platformEndpointRequest = new CreatePlatformEndpointRequest();
platformEndpointRequest.setCustomUserData(customPushData);
platformEndpointRequest.setToken(pushNotificationRegId);
platformEndpointRequest.setPlatformApplicationArn(platformApplicationArn);
CreatePlatformEndpointResult result = pushClient.createPlatformEndpoint(platformEndpointRequest);
Also, unless your SNS app Region is US_EAST_1, I've found you have to manually set the region or you'll receive a mismatching region error response, so before calling createPlatformEndpoint() set your region like follows:
//Replace with whatever region your app is
pushClient.setRegion(Region.getRegion(Regions.US_WEST_2));
I created a custom receiver for Chromecast that plays video and I am trying to send messages back to my Android sender app on the same namespace. I'm currently doing it this way in Javascript:
window.castReceiverManager = cast.receiver.CastReceiverManager.getInstance();
window.castReceiverManager.start();
//use namespace urn:x-cast:com.google.cast.media to communicate to VideoCastManager in Android...?
window.customMessageBus = castReceiverManager.getCastMessageBus('urn:x-cast:com.google.cast.media', cast.receiver.CastMessageBus.MessageType.JSON);
//overwrite the onMessage function
var defaultFunction = window.customMessageBus.onMessage;
window.customMessageBus.onMessage = function(event) {
window.senderId = event.senderId;
window.message = event.data;
defaultFunction(event);
};
//send message
window.customMessageBus.send(window.senderId, {message: "test"});
In Android, I am trying to receive the messages in this way:
mCastConsumer = new VideoCastConsumerImpl() {
//removed all the other override functions to save space
#Override
public void onDataMessageReceived(String message) {
System.out.println("CAST RECEIVED MESSAGE:" + message);
}
};
This doesn't work, and I was hoping someone could point me in the right direction?
Thanks
You need to use a custom namespace not the Media namespace.