I would like to send in-app and cloud messages to a group of users based on non-standard criteria.
I decided to link firebase project with BigQuery and use imported segments to accomplish this task.
The problem is that fcm message composer always target 0 users when i filter users based on the segment.
I added such entry to the SegmentMetadata table
{
"segment_label": "test_segment_label",
"display_name": "test_display_name_metadata"
}
and such entry to the SegmentMemberships table
{
"instance_id": my device fcm token,
"segment_labels": [
"test_segment_label"
],
"update_time": null,
"membership_name": "test"
}
Now on the firebase console when i am trying to send cloud message and target users based on this segment i see that 0 users are matched, do you have any idea why?
image snapshot from firebase console
(my device fcm token that i putted on the entry in the SegmentMemberships table should be valid because i see on android studio logs that it doesn't change)
instance_id is not your fcm token but the part before colon in your token.
When you call getToken() in SDK the token returned is in this format: <instance_id>:<token>
Related
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));
Recently I migrated from GCM to FCM for sending the notification via my app, i want to know whether can able to subscribe the members in particular topic from my app server. If possible, then how will find out if a particular member token valid or expired.
Because in my database, i have near to 22L people GCM Registration TOKEN id, so that i will create one topic and subscribe those members via my app server.
Any ideas to resolve this kind of issues.
You can subscribe multiple tokens to Topic via your App Server using the Instance ID API, specifically, using batchAdd. It can also identify if the Registration Token that you were subscribing is invalid by returning a NOT_FOUND error. From the docs:
Manage relationship maps for multiple app instances
Using the Instance ID service's batch methods, you can perform batch management of app instances. For example, you can perform bulk addition or removal of app instances to an FCM or GCM topic. To manage app instances, call the Instance ID service at this endpoint, providing the app instance tokens in the JSON body:
https://iid.googleapis.com/iid/v1:batchAdd
https://iid.googleapis.com/iid/v1:batchRemove
Parameters
Authorization: key=YOUR_API_KEY. Set this parameter in the header.
to : The topic name.
registration_tokens : The array of IID tokens for the app instances you want to add or remove.
Results
On success the call returns HTTP status 200. Empty results indicate successful subscription for the token. For failed subscriptions, the result contains one of these error codes:
NOT_FOUND — The registration token has been deleted or the app has been uninstalled.
INVALID_ARGUMENT — The registration token provided is not valid for the Sender ID.
INTERNAL — The backend server failed for unknown reasons. Retry the request.
TOO_MANY_TOPICS — Excessive number of topics per app instance.
Example POST request
https://iid.googleapis.com/iid/v1:batchAdd
Content-Type:application/json
Authorization:key=API_KEY
{
"to": "/topics/movies",
"registration_tokens": ["nKctODamlM4:CKrh_PC8kIb7O...", "1uoasi24:9jsjwuw...", "798aywu:cba420..."],
}
Example result
HTTP 200 OK
{
"results":[
{},
{"error":"NOT_FOUND"},
{},
]
}
We have an Android education app and we use FCM Topic Messaging for sending specific notifications to each user. We categorized each user according to academic year.
Now, we have one problem for topic messaging, in the specified time, these students goes to one level higher and if we don't change the topic in Firebase for new academic year, it gives the last year notification.
How can we do this? Does Firebase have a solution for this problem? Thanks <3
This can be done through your App Server by using the InstanceID API.
You can batchAdd the corresponding tokens to the new topic (i.e. academicy year) you need, then batchRemove them from the old topic (i.e. last year).
From the link above:
Manage relationship maps for multiple app instances
Using the Instance ID service's batch methods, you can perform batch management of app instances. For example, you can perform bulk addition or removal of app instances to an FCM or GCM topic. To manage app instances, call the Instance ID service at this endpoint, providing the app instance tokens in the JSON body:
https://iid.googleapis.com/iid/v1:batchAdd
https://iid.googleapis.com/iid/v1:batchRemove
Parameters
Authorization: key=YOUR_API_KEY. Set this parameter in the header.
to : The topic name.
registration_tokens : The array of IID tokens for the app instances you want to add or remove.
Results
On success the call returns HTTP status 200. Empty results indicate successful subscription for the token. For failed subscriptions, the result contains one of these error codes:
NOT_FOUND — The registration token has been deleted or the app has been uninstalled.
INVALID_ARGUMENT — The registration token provided is not valid for the Sender ID.
INTERNAL — The backend server failed for unknown reasons. Retry the request.
TOO_MANY_TOPICS — Excessive number of topics per app instance.
Example POST request
https://iid.googleapis.com/iid/v1:batchAdd
Content-Type:application/json
Authorization:key=API_KEY
{
"to": "/topics/movies",
"registration_tokens": ["nKctODamlM4:CKrh_PC8kIb7O...", "1uoasi24:9jsjwuw...", "798aywu:cba420..."],
}
Example result
HTTP 200 OK
{
"results":[
{},
{"error":"NOT_FOUND"},
{},
]
}
If I send push message by selecting a package from Firebase console, the push goes to all devices, but during sending to individual device, it displays the error:
Invalid reg token,please check token format
Error Snapshot:
UserID in console is not the registration token for Firebase messaging. By Firebase docs:
on initial startup of your app, the FCM SDK generates a registration token for the client app instance. If you want to target single devices or create device groups, you'll need to access this token by extending FirebaseInstanceIdService.
My last registration token looks like
cpeBAc1NkUE:APA91bEpAKHQTdgkWVdDzDZG8BPon0APaIhbbuSejDpZF-FO1gD2saDV7_EQDo2WEz0H6e5U-uf0i-v4b25NXgGzV2oUrNuboM5675WY7VCP3JcBl8BCNY7eV0VFGHT9oRox0EEoo_ch
In the other answer, you mentioned in the comments that you're Registration Token is:
cbuJIjkg9zQ%3AAPA91bHavuWCuRuWIBrDOoHUK-RsjU1yewigurrYzHe0cPiTQINykKjrLf8E0qEwJj3XmJ1IoTmn0r2EoLR_mAHGOjlA61CnQ8aSn2WxWKKByOwbsnqoVeaeWQIeGU_yh4wnZ67soLtI
I noticed the % (percentage character) included in it, which isn't a usual character included in registration tokens. Figured that it was possible that this was encoded somehow. When decoded, this is the value:
cbuJIjkg9zQ:APA91bHavuWCuRuWIBrDOoHUK-RsjU1yewigurrYzHe0cPiTQINykKjrLf8E0qEwJj3XmJ1IoTmn0r2EoLR_mAHGOjlA61CnQ8aSn2WxWKKByOwbsnqoVeaeWQIeGU_yh4wnZ67soLtI
Notice that the %3A was turned into : (colon). This is one of the usual characters. So I would suggest that you try the value above.
And as a reminder, the InvalidRegistration error (emphasis mine):
Check the format of the registration token you pass to the server. Make sure it matches the registration token the client app receives from registering with Firebase Notifications. Do not truncate or add additional characters.
Don't even encode it. Use it as is. Also, do note that the Registration Token should be kept secret.
I have a problem with an app using GCM, the scenario is this:
the app is installed
the app calls the GCM register method getting the registration id "RID-1"
the app is uninstalled
the app is installed again
the app calls the GCM register method again getting the registration id "RID-2"
In step 5, I need to get the previous registration id so I can update my model.
Limitations:
- I am trying to do this without using the external storage
- I can't update the model when the server sends a message, it should be done after the registration because a new profile is created in the app for each new device
I know that this information is in Google servers because it is sent to you when you send a message to the old registration id. For example, if I send a message to "RID-1", in the response I get that the new (canonical) registration id is "RID-2". What I need is a way to get this information without sending a message.
Let me know if you need more context.
I found several related questions but the answers doesn't apply to this scenario:
Registration ID duplication for GCM
gcm canonical id should be updated or not
Persistance of gcm registration id
Google Cloud Messaging - Registration ID status
Android GCM: How to detect registered canonical ids in my own server?
Handling registration ID changes in Google Cloud Messaging on Android
(all answered by #eran)
You can specify "dry_run": true option in /send request.
I found that devices do not receive any push notifications with "dry_run": true option, while a server get canonical_ids response.
Here is a sample code in Ruby. You may have to install gcm Gem beforehand.
$ gem install gcm
ask_canonical_ids.rb
require 'gcm'
require 'json'
API_KEY = "YourApiKey"
gcm = GCM.new(API_KEY)
registration_ids = [
'OldRegistrationId',
]
option = { data: { 'message' => 'Hello Gcm!' }, dry_run: true }
response = gcm.send_notification(registration_ids, option)
p response[:canonical_ids]
output of $ ruby ask_canonical_ids.rb (formatted)
[{
:old => "OldRegistrationId",
:new => "NewRegistrationId"
}]
Again, your device will not receive any push notifications.
We need to update registration id with Canonical Id( By finding index position of array). You may Follow this working Ready use Code
If all you need is that the user should not get a notification, send a message with parameters that your application is not looking for. You will get the canonical and your app will discard the notification if it does not have the mandatory text and message.
For example, my Cordova application plugin requires the key 'message' in the data received from the server. Otherwise it does not create a notification.
I know this is sort of a hack, but I think given the limitations, this will be the easiest to achieve.