From Google Developer website, I found that GCM Token may be changed after period of time:
The Instance ID service initiates callbacks periodically (for example,
every 6 months), requesting that your app refreshes its tokens. It may
also initiate callbacks when:
There are security issues; for example, SSL or platform issues.
Device information is no longer valid; for example, backup and restore.
The Instance ID service is otherwise affected.
I have an android app using GCM Topic subscriptions to send push notification, in this case, when token has been refreshed, do I need to re-subscribe all topics again or GCM server will automatically do it ?
Thank you in advance.
I have tested that when token is refreshed (you receive a new token) you have to register all topics again.
Also checkout this SO
Sample test:
Get token ("...b43sCSdoEDkU54SIWll3hbDVsd7E1UdwlAvp4LP")
Register for topic.
Send notification for topic
Works!
Restart few times app and still get notification for topic
Force call
instanceID.getToken(defaultSenderId, GoogleCloudMessaging.INSTANCE_ID_SCOPE);
Token refreshed ("...XVT_pZq7fy_vKmskiGpDXMyqdAF6ODl_46JMdi5")
Send notification for topic. I don't get it!
More details:
Tool #1
Use this to check google gcm data
Reinstall app
Get new token ("")
Response from tool #1
{
"applicationVersion": "39",
"connectDate": "2016-01-12",
"application": "com.esportlivescore.develop.debug",
"authorizedEntity": "11443413691531",
"connectionType": "MOBILE",
"appSigner": ".................",
"platform": "ANDROID"
}
Subscribe for topic
Response from tool #1
{
"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"
}
Messages for topic are working
Request new token (refresh)
Google resend me old token :)
Again...
Now i don't have any subscriptions :(
Related
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.
There are several posts and discussions about uninstall tracking of iOS and Android apps.
We would like to achieve this as well and tried the suggested solutions, but we found out, that this does not work as expected.
The way this should be done is to send a silent push to the device token and then checking the response if it was successfully.
In our case, the response is always
success:1
until the device itself requests or receives a new token and this only happens when the app is installed.
Maybe the token expires on its own, but this is not an option (I found a comment who mentioned the token will expire after 24 months, this is to long for uninstall tracking).
Maybe we are doing something wrong, but this is our way:
Silent push via https://fcm.googleapis.com/fcm/send
{
"to" : "{device-token}",
"content_available": true,
}
respond is
{
"multicast_id": {any-id},
"success": 1,
"failure": 0,
"canonical_ids": 0,
"results": [
{
"message_id": "{any-id}"
}
]
}
this response only gets success:0 failure:1 when the app itself receives / requests a new token, and the message is sent to a previous one, but this is only the case when it is still installed.
Another idea would be to send a silent push, which triggers a web call from the app to the server. If the call is received during a defined time, the app is installed, if not, its marked as uninstalled. But this only works if the app is not fully closed on android (force close).
We also tried the ttl or apns-expiration but this does not work as well as we expect it.
Question:
what do we have to change in order to recognise the uninstall via silent push notification, or what are the requirements to achieve this or we have to be aware of?
How and when is the push token invalid when an app gets uninstalled?
After setting up Android real-time developer notifications (RTDN) as a way to receive IAP subscription state changes to my web server, I only actually receive a certain push from Google's RTDN webhook that never includes the subscription details. Below is the payload structure that gets delivered to my server every time a purchase subscription event happens from my app:
"message": {
"data": "longstringofcharacters",
"messageId": "604411111111111",
"message_Id": "60442222222222",
"publishTime": "2019-07-03T11:03:34.076Z",
"publish_time": "2019-07-03T11:03:34.076Z",
},
"subscription": "projects/api-keyname/subscriptions/my-project-name"
According to Google's RTDN setup guide (https://developer.android.com/google/play/billing/realtime_developer_notifications.html), the below format is what I should expect to receive anytime a new subscription is purchased, cancelled, restored, or undergoes any other related state change from a user in my app:
{
"version": string,
"packageName": string
"eventTimeMillis": long
"subscriptionNotification": SubscriptionNotification
"testNotification": TestNotification
}
I have gone through Google's RTDN setup guide a number of times, and made sure my topic has granted publisher permissions for "Pub/Sub Publisher" using "google-play-developer-notifications#system.gserviceaccount.com" which Google says is a necessary step; doing this I believe is the reason why I'm able to receive webhook transmissions, but for some reason I don't understand why subscriptions events aren't getting transmitted.
Ultimately, my goal is to receive the correct payload which contains IAP state change details so that automatically syncs with my user database on my server.
Has anyone experienced this with RTDN when attempting to receive IAP push notifications?
I figured it out: I missed in Google's guide that the payload I was expecting was base64 encoded in the "data": "longstringofcharacters" portion I pasted above. Once I realized that, I decoded one from my logs, and found the IAP subscription details I was expecting.
According to Android developer guide. Our server will receive Pub/Sub notification when a user buy or cancel a subscription.
But it seems we don't have any information to identify the user. How can I modify the user's data in my server accordingly?
Below is the notification I received
{"version":"1.0","packageName":"com.diamondtech.streammap","eventTimeMillis":"1557833856021","subscriptionNotification":{"version":"1.0","notificationType":2,"purchaseToken":"celgdoceflgifibejhfgafpd.AO-J1OxoputCKFIjQt7QgnF5hSg8jiqDCNEiBM-8kBEOTwXr4oy-33LGr8l6h2Ih1GXX7yjgcptIaatVFN5EHT4_sywD5-qruOhOJZVdwBnGM71-8N-xxxxxxxxxxx","subscriptionId":"premium"}}
And the response of the google verification API
{ "kind": "androidpublisher#subscriptionPurchase",
"startTimeMillis": "1557832655139", "expiryTimeMillis":
"1557834750372", "autoRenewing": false, "priceCurrencyCode": "TWD",
"priceAmountMicros": "160000000", "countryCode": "TW",
"developerPayload": "", "cancelReason": 1, "orderId":
"GPA.3318-4223-0272-90442..6", "linkedPurchaseToken":
"cjnnjplpglkmdmdhbhaecobo.AO-J1OzD_JJr1Z8pzSDvJSjujfHVp9EQUsUnBv2kf5JocYsXpT-rX954WIuOSAtmLbMzqJmHudnwvsJll1GnXThj6JoDFSAR2E01fa4eZ7lUIozMOh4a_xxxxxxxxxxxx",
"purchaseType": 0 }
Very late answer but since there are no answers maybe this can help someone at least.
You only get personal information if the customer used "Subscribe with Google":
https://developers.google.com/news/subscribe/
If you have an app where the user buys a subscription, you get a receipt from Google with a purchaseToken. And since you know which user it is in the app, save the user information together with the receipt (most importantly the purchaseToken) in your database.
When you get a notification, match the purchaseToken in the notification with your database to determine which user it belongs to.
Do note that if a user cancels and then resubscribes they will get a new purchaseToken and the original one will be in the receipt from Google under "linkedPurchaseToken":
https://developers.google.com/android-publisher/api-ref/purchases/subscriptions#resource
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.