What function does RemoteMessage.send() trigger on Firebase? - java

What I really need to accomplish is an instant messaging feature using Firebase.
I've been reading the Firebase Cloud Messaging docs, but I get very confused about the pourposes of the example codes on the server side.
I thought about this solution:
Send a message on the client app to Firebase via RemoteMessage.send()
On Firebase, I catch that message and "redirect" it to the message reciever, who is another client of the app.
In my client app I have this code that I took from the documentation (Firebase was previously initialized):
instance.send(new RemoteMessage.Builder(senderID + "#fcm.googleapis.com")
.setMessageId(Integer.toString(messageID))
.addData("message", message)
.addData("action", "SAY_HELLO")
.build());
That would be the first part of the solution, but now I'm stuck on the part of the code where Firebase should "catch" the message and sends it to another user.
I was trying to write a node.js function to accomplish this, but the problem is that I don't know what is triggered when Firebase gets a RemoteMessage.
Would you mind explaining me how can I do this?
Any code example will be welcome. Thanks :)

Related

using firebase cloud messaging how can I understand which message give me an error and which message is accepted for delivery?

I have a DB in which I saved a list of message that I have to send using firebase cloud messaging.
If I want to send up to 100 messages in batch for better efficient how can I understand which of the message in my db was sended correctly and which one give me an error?
I have seen that the response are something like this for the error response:
error: {"error":{"code":400,"message":"Invalid condition expression provided.","status":"INVALID_ARGUMENT","details":[{"#type":"type.googleapis.com/google.rpc.BadRequest","fieldViolations":[{"field":"message.condition","description":"Invalid condition expression provided."}]},{"#type":"type.googleapis.com/google.firebase.fcm.v1.FcmError","errorCode":"INVALID_ARGUMENT"}]}}
for the message accepted we have something like this:
id: projects/id_project/messages/0:1563809489349852%31bd1c9631bd1c96
How can I understand which message had an error so I can try to send it again or handle that error. Moreover I want to understand even which message was sended correctly.
any advice?
Thanks in advance.
The order of the responses corresponds to the order of the input messages in a batch. From the API docs of the Java Admin SDK:
The responses list obtained by calling getResponses() on the return value corresponds to the order of input messages.
Same is true for other implementations of the Admin SDK that supports FCM batch messaging.

How to send push notifications to specific users firebase

I'm trying to send out a push notification from a teacher to a student, for example. I'm using firebase and I've already got that token from each device and saved it on firebase to the wanted user, and setup my FirebaseMessagingService.
Now I want to be able to send a notification, programmatically, whenever a teacher clicks on a student in a list, for example.
How do I do that? I've been looking for a solution for a couple of days and couldn't find an answer.
Thanks :)
This is what I did. And it works. I know, because I was up all night trying to get this thing to work.
admin.messaging().sendToDevice(token, msg)
.then(resMsg => {
console.log("Successfully sent message", resMsg);
}).catch(err => {
console.log("Error sending message", err);
})
Where token is the FCM token from the client device.
And the msg is a JSON payload of the following structure:
const msg ={
notification: {
title: 'It\'s the last day of the week!',
body: `It's Sunday! Don't forget to refresh Dashboard with your latest activity data!`,
},
};
Source Build a transactional push notifications system using only Firebase
For sending push notifications with firebase you need to use the FCM API which can be found here: https://firebase.google.com/docs/cloud-messaging/server.
Assuming you use Java for your software you could take a look at this quickstart example provided by google: https://github.com/firebase/quickstart-java/blob/master/messaging/src/main/java/com/google/firebase/quickstart/Messaging.java or look for a complete library.
You just need to add some logic to your application that triggers the FCM API with the correct token and payload.

How to push notification with Cloud Messaging Firebase from the server

I already have an app and I want to start sending notification to the users. I already set up everything in the app(using react native) and I checked manually that I can send notification to the devices and it works.
Now I want to run a job in the server who will push the message (with the device token) to the cloud messaging in firebase.
I can't find a lot of details about how to do it. I would like if someone can give me any guide I can use with. my server is in Kotlin(java can be good too) and I m working with gradle.
Thank you so much for the help
From a Java server you can use the Firebase Admin SDK to send messages. From that documentation comes this minimal example:
// This registration token comes from the client FCM SDKs.
String registrationToken = "YOUR_REGISTRATION_TOKEN";
// See documentation on defining a message payload.
Message message = Message.builder()
.putData("score", "850")
.putData("time", "2:45")
.setToken(registrationToken)
.build();
// Send a message to the device corresponding to the provided
// registration token.
String response = FirebaseMessaging.getInstance().send(message);
// Response is a message ID string.
System.out.println("Successfully sent message: " + response);
Note that this sends a data message, so that will always be delivered to your code, where you can decide to display a notification or not. To send a notification message, which is what the Firebase console does, you'd use:
Message message = Message.builder()
.setNotification(new Notification("This is the title", "This is the body"))
.setToken(registrationToken)
.build();
Both of these send the message to a specific registration token, so only to a single device/app instance. This means you will need to maintain a list of these tokens, in a way that allows you to send the messages to fit your needs. E.g. a common way is to store the tokens per user. For an example of that, see the functions-samples repo. While this example is in Node.js, the same logic could be applied to a Java server.
Finally: you can also send message to topics. For an example of that (again: using a Node.js server), have a look at this blog post Sending notifications between Android devices with Firebase Database and Cloud Messaging.

Android/Firebase - Check to see if you are subscribed to topic

I am wondering if there is a way to test to see if you are subscribed to a topic on the android side of things.
Basically, I am HOPING that all devices will subscribe to a topic during their installation, when the token is first obtained by the device. However, there is always a chance that the device fails to subscribe. The FCM registration token should be installed on the device for a long time, and thus, the onTokenRefresh() method shouldn't be called again without clearing data, uninstall/reinstall, etc.
My idea was to test to see if the device is subscribed to a topic in my MainActivity, and if not, then try to subscribe again. If it fails to subscribe, then get a new token and try again, etc.
#Override
public void onTokenRefresh() {
// Get updated InstanceID token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.e(TAG, "Refreshed token: " + refreshedToken);
// Subscribe to a topic
Log.e(TAG, "Subscribing to topic");
FirebaseMessaging.getInstance().subscribeToTopic("test");
So, I can subscribe and unsubscribe, but how do I check if the device is subscribed to a topic? I did my fair share of googling, and couldn't find anything, unfortunately.
I would greatly appreciate any/all assistance. Thanks!
There is currently no way to check on the client side if they are subscribed to a topic.
The behavior for subscribeToTopic is it would immediately subscribe to the specified topic, if it fails, it would retry on it's own (unless your app was killed). See my answer here.
I think that forcing the onTokenRefresh call just to make sure that subscribeToTopic is too much. You could simply just call it in your initial activity if you want, that way, everytime the app starts, it sends the subscription request.
Actually this can be done by using this api: https://developers.google.com/instance-id/reference/server#get_information_about_app_instances
As IID_TOKEN you need the FCM token and in the header you have to pass Authentication: key=YOUR_SERVER_KEY. You can find the server key as described here: Firebase messaging, where to get Server Key?.
Don't forget to include details=true as query parameter in the url, otherwise the topics won't be included in the response.
I would recommend writing a Cloud Function to encapsulate it, so you don't deploy your server key to the client.

How to send direct message via Firebase from user to user?

I am really rookie and need an advice.
I have read documentation, and as far as i understood if you need send direct message, follow next steps:
Make authentification, eventually you get Firebase TokenId and
userId
Send them to your server side and store it in DB
When you are going to send a message you need create json and put
inside topic text and resipent userId so on...
Send this json via HTTP to your server side
When server retrive this json, it should use Firebase API to
create new message bloc child with random name in firebase
Eventually server have to find recipent user in DB by userId that we get from message.
After server will find current recipent user by userId , next we should take firebase tokenId In order to sent notification .
And send recipent user notification with such data - name of new
message bloc child
Recipent will connect to this current bloc and retrive data
It is as i understood this consept, fix me please if smth wrong?
Your suggested approach sounds good. The most important thing to realize is that you require an app server to send a downstream message to a device. Using the database as the communication mechanism between the app and the app server is a popular approach.
You could also use Cloud Messaging's upstream capabilities. But I've never tried that approach, because the database works fine for me and I had little interest in learning yet another protocol (XMPP).
You can read how I implemented it in this Firebase blog post Sending notifications between Android devices with Firebase Database and Cloud Messaging.

Categories