I have a scenario in my app such that, a certain event occurs and I have a list of user-id/tokens and I need to send the notification to all of those n devices.
To trigger the fcm with n tokens , n time will not be feasible
so I should create a topic dynamically and subscribe those n users's device id/ token to that topic.
I know I can do it from the client app , but is it possible to do that from backend.
I am using Phoenix as my backend.
I found the way, writing this answer in case it help others in future
Yes Its possible to create a topic dynamically if we have the list of
valid registration tokens
This is the endpoint url if you want to generate a topic , given you have a list of users-
https://iid.googleapis.com/iid/v1:batchAdd
The Authorization header contains-
Content-Type- application/json
Authorization- key=<your-server-key>
The body parameters look like-
{
"to": "/topics/<topic name>",
"registration_tokens": [
"token1",
"token2"
]
}
And now the topic is created,
You can easily sen message to that topic with- https://fcm.googleapis.com/fcm/send
Authorization token is same as previous one
And body as-
{
"priority": "HIGH",
"notification": {
"title": "New Text Message",
"image": "https://firebase.google.com/images/social.png",
"body": "Hello how are you?"
},
"to": "/topics/<topic name>"
}
To trigger the fcm with n tokens , n time will not be feasible
Using topics does not inherently change how FCM message delivery works. When you use a topic, the Google servers keep a mapping of that topic to the subscribed tokens. So when you call the API to send a message to a topic, the Google servers fan-out from that topic to the tokens, and then deliver the message with the same infrastructure as when you call the API with the tokens yourself.
Since you already have the tokens, so it might be simpler to just send to them directly, rather than creating a one-off topic.
Related
I have an app with Android and iOS users, subscribed to Firebase Clould Messaging topics. Some users have access to send a message to these topics. I make an http request to send the message. The body looks like this:
{
"to": "/topics/debug"
"notification" : {
"body" : "Hi there",
"title" : "Wow!",
"sound": "default"
},
"priority": "high"
"data": {
"title": "Hi there",
"body": "Wow",
}
}
For android, in order to send data message, I need to use the "data" key, so that onMessageReceived is called.
However, ios needs the "notification" key, so that even if the app is killed the message will display. But, whenever I add the "notification" key, the android devices don't call onMessageReceived, and it isn't treated as a data message.
How can I solve this issue, to make one request which is work for both devices. If I do two requests (one with "notification" for ios, and one with "data" for android, the android devices get two notifications (one from onMessageReceived, and one from the system. Can I stop the android devices from showing the message if its sent with just the "notification" key?
I hope I explained the issue well, since this is how I understand the problem I have.
Thanks
I'm not sure this counts as an answer, but I realised an easy workaround, that I prescribed different topics to android and ios users, and set different code appropriate for each one, instead of having one topic for all users.
I am using Firebase for my android studio project and I want to have a notification button so that whenever a user clicks a send button, the notification button indicates there is a new notification and that notification contains the data that the user sent. Is it possible to do so using firebase ? and how ?
Sure. You want to use Topic Messaging in FCM.
Here's the setup guide.
Once implemented, subscribe a user with:
FirebaseMessaging.getInstance().subscribeToTopic("dogs")
And send a notification via a POST request on the app (insecure, not recommended) or via a server (recommended):
POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1
Content-Type: application/json
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
{
"message":{
"condition": "'dogs' in topics || 'cats' in topics",
"notification" : {
"body" : "This is a Firebase Cloud Messaging Topic Message!",
"title" : "FCM Message",
}
}
}
I don't know, whether you figured it out or not (because you asked the question months ago), but I may have an idea. Actually I was also searching for what you asked to do, and I read your question. I wanted to do the same thing as you. Then I thought, if firebase cloud messaging service can receive http POST request not just from firebase console but also from any other service like ARC (Advanced REST client).
So the solution :
Send a JSON HTTP post from your app when the users click on the app with the required data received from user. Now when the JSON response is received by the firebase cloud messaging server, it should you the notification to every user with the data sent by the user who clicked the button.
I haven't tried it yet but I am going to try it now. I will let you know in the comments if it works or not. It should work theoretically. If you have already figured out a way to send such notifications, please don't forget to share your method.
If you want to know how to send JSON HTTP post, then here is a stack overflow answer : SENDING JSON OBJECT
I am creating a college Android application where faculty choose the specific course and send them assignment notification but how i do that i don't Know... please help me..
You need to subscribe topic from Android app. Send notifications to that topic so it will received to all users who has subscribed it.
Sample code subscribe top from Android app.
FirebaseMessaging.getInstance().subscribeToTopic("news");
Send message to this topic from server-
URL- https://fcm.googleapis.com/fcm/send
Body-
{
"to": "/topics/news",
"data": {
"message": "Message to user",
"title":"title of message",
"sender":"sender name"
}
}
headers- api key from firebase
Rest you need write code from Android and Server side.
You can also send notifications form Firebase console as well.
As per my previously asked question, Firebase onMessageReceived not called when app is in the background , I need to change the payload to a 'data' payload as opposed to a 'notification' payload. (See link here -- What is the difference between Firebase push-notifications and FCM messages?).
The problem is, both the IOS and Android app we have utilize Firebase and the IOS app requires the push notification payload to use the 'notification' structure, while Android requires the 'data' payload structure.
My question is therefore, how do you distinguish between Android and IOS tokens / Ids obtained via the firebase sdk?
If our server saves these Ids and needs to send out a push notification, it needs to specify Android vs IOS in order to change the payload structure. Is the only way to accomplish this identification to have an app-based call to the server which differentiates IOS vs Android? Or is there a more sophisticated way using Firebase that will allow us to poinpoint which device it is?
Thanks all.
Information about an app instance is available from the Instance ID Service at this endpoint:
https://iid.googleapis.com/iid/info/IID_TOKEN
On success the call returns HTTP status 200 and a JSON object containing various status for the app instance including the platform:
returns ANDROID, IOS, or CHROME to indicate the device platform to
which the token belongs
I faced the same issue, following is my approach to solve the issue.
Firebase supports "Topic messaging", in which we can send data or notification messages to multiple subscribed devices.
Lets consider user login email id is unique (Lets consider example email id is test#gmail.com), In android application user will subscribe to test_gmail.com_data topic (replace '#' with '_' in email id since topic name doesn't support '#') and in iOS application user will subscribe to test_gmail.com_notification topic, From cloud functions I am sending Data message which is intended to android device on data topic and Notification message which is intended to iOS devices on notification topic.
By this approach I solved the issue, only problem with this approach is we end up sending twice the same message.
Example Code :
const data_message = {
data: {
"sender": "Narendra",
"Message" : "Simple data message"
},
topic:"test_gmail.com_data"
};
const notification_message = {
notification: {
title: "Announcement"
},
data: {
"sender": "Narendra",
"Message" : "Simple data message"
},
topic: "test_gmail.com_notification"
};
promises.push(admin.messaging().send(data_message));
promises.push(admin.messaging().send(notification_message));
I had subscribed to topics from GCM and when I removed all app data by android settings, the GCM token is the same and GCM notification on topics are still available, so I get notifications which I don't want to receive.
My questions are:
How can I get list all of subscribed topics from GCM?
How can I remove all subscribed topics without knowing their names?
Should the GCM token be changed after clearing app data or should all subscribed topics be removed automatically in this case?
You can't only you can use tool for debug i suggest :)
You have to save subscribed topics for example in sharedprefs. If you don't have token in sharedpreferences you should call instanceId.deleteInstanceID()
Simply call instanceId.deleteInstanceID()
Token will change rarely but when it changes you must resubscribe all your topics.
Also checkout this question on SO
TOOL
You can use this tool to debug :)
When i don't subscribe any topic i get something like this:
{
"applicationVersion": "39",
"connectDate": "2016-01-12",
"application": "com.esportlivescore.develop.debug",
"authorizedEntity": "114434000000000",
"connectionType": "MOBILE",
"appSigner": ".................",
"platform": "ANDROID"
}
After i subscribe some topic:
{
"applicationVersion": "39",
"connectDate": "2016-01-12",
"application": "com.esportlivescore.develop.debug",
"authorizedEntity": "11443413691531",
"rel": {
"topics": {
"match-28388-start": {
"addDate": "2016-01-13"
}
}
},
"connectionType": "MOBILE",
"appSigner": ".................",
"platform": "ANDROID"
}
So somple usage. I use Advanced REST Client (plugin for Chrome)
HTTP GET Request
https://iid.googleapis.com/iid/info/<TOKEN>?details=true
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA
TOKEN in url : token obtainet from google
key : can be found in Google Developer Console / GCM Console
How can I get list all of subscribing topics from gcm?
The current version of GCM doesn't provide a method to do this.
How can I remove all of subcribing topics without knowing their names?
The documentation indicates InstanceId.deleteInstanceID() will do this.
Should GCM token be changed after clear app data or removed all
subscribing topics in this case automatically?
Although the documentation implies that token registrations and subscriptions are removed if the user clears app data, that is not true in the current version of GCM. The issue is discussed in the answer to this related question.