I am using Uniqush to send GCM messages to an app I'm developing, and so far this is working well. However, for obvious reasons I am uninstalling and reinstalling the app as I develop, and it's re-registering for GCM with each new install.
I understand GCM is supposed to handle this automatically:
http://developer.android.com/guide/google/gcm/adv.html#unreg
if a message can't be delivered to a device, it sends an error to the server, which handles it. Unfortunately (even after sending a test push message while the app wasn't installed) I am getting duplicate messages to my device.
Is this a failure in Uniqush, my program, GCM, or some combination of the three?
If notifications are sent to a device while it has the app uninstalled, eventually the duplicates clear.
Given your description, I am unable to reproduce your situation. Here are the steps to try to reproduce it:
Install the test app on my phone and push notification to it using uniqush. Correct. Uniqush's log shows it is successfully delivered and my phone shows the correct result.
Uninstall the test app.
push another notification again using uniqush. Uniqush's log shows the message saying the user is unsubscribed the service: [Unsubscribe][Info] 2012/12/21 19:18:08 [UnsubscribeRequest] RequestId=3992a14e4987e94e3ce16bb7394ee06d2d9e7231 Success
DeliveryPoint=gcm:47e6551857be173b1418e56b63dbdb8cd58c94a2
Then push one more notification to the device, uniqush says it cannot find the device (because it has already been removed.)
Check the database using redis-cli, the device's information is no longer stored. It is successfully unsubscribed.
However, I did found some problem: if you check the error message returned from uniqush from HTTP, then you will see Success on the second notification. I have already fixed this bug in next release. It will be online soon. (If you are interested in that, check the .deb package )
In fact, uniqush is designed to be able to handle such situation so that the user don't need to care about unsubscription, device token/registration id update, etc.
If you have any future question, please feel free to comment or contact me.
Related
I have a Xamarin Forms application where we're using Azure Notification Hub to send messages to both Android and iOS devices.
Whenever someone logs into the application a record is created (or updated) for that device. Various information about that device is stored: who it belongs to, installation id, token, etc.
We then call the hub method CreateOrUpdateInstallationAsync() for that device's installation. In the case of a new install or cleared data we will be passing in a new installation to Azure Notification Hub to create the installation. In the case of an existing installation we're simply updating the tags so that the correct user will be notified when a message is sent.
This all seems to work as expected. After the call to CreateOrUpdateInstallationAsync() we will see both a Native and a Template registration in the hub for a given installation id. I can log in and out of the application and those device records are updated in the hub. I can see the tags change.
However, for some reason, some Android devices will stop receiving notifications. Sometimes this is immediate. That is, right after the app is installed and the device is registered with the hub, it can't receive messages. Other times it could take up to 24 hours or so, but a device that was receiving messages will suddenly stop.
If I use the Azure Portal to try and directly send a message to the broken Android device it tells me that there are "no matching targets". If I use the Firebase console to send a message to the broken device the message is never received.
iOS never seems to have an issue.
I'm unsure how to proceed. It's almost as if the FCM token is invalid at some point. From what I've read the only time it really should become invalid is if the app is newly installed, the data was cleared, or the device was restored. But this invalidated token seems to happen immediately after install or after a day or so of previously receiving notifications without issue.
If this is the case, is there some way I'm supposed to be aware of this when sending a template message through the hub?
My app is using Google's C2DM (push notification) to notify users about new activity from friends. Once they install the app I register the device with C2DM servers and store user's phone number. So I know that the user is using my app and I can send him/her the push notifications. But what happens if users uninstalls my app, is there a way to catch it in my app? Or the only way is to catch an error on my server when I send a C2DM and it's unreachable, then mark a user as inactive?
I would love to notify users when their friends are using an app and when they no longer do.
What's is the best solution for this scenario?
The GCM documentation explains this situation here:
https://developers.google.com/cloud-messaging/registration#how-uninstalled-client-app-unregistration-works
"An application can be automatically unregistered after it is uninstalled from the device. However, this process does not happens right away, as Android does not provide an uninstall callback."
Basically when GCM tries to send the next push notification, the device will tell GCM the receiving application was uninstalled.
As for notifying friends that their friends aren't using the app any more, GCM will send a NotRegistered error to your notification server when this failure occurs; it won't be immediate, but could you use that?
Unfortunately the ACTION_PACKAGE_REMOVED intent will be sent out to all receivers except for your own. This is confirmed here.
Some questions for your C2DM plan, since I'm not very familiar with it. If the user just leaves their device off for a long period of time, will that trigger the error condition you use? How does C2DM actually report an "unreachable" device? Is that a condition that only occurs when it attempts to send the push notification and fails or is it when it somehow determines it reaches the device but fails to be handled properly? Obviously in the second scenario your plan would work, but I can see some "false positives" occurring otherwise.
Older SO question for reference: android not receiving Intent ACTION_PACKAGE_REMOVED in the removed package
Yes, but it is quite hacky.
The method is based on the fact that the first thing android does when uninstalling your app is deleting your data file. So you could use a file watcher to detect the deletion.
Also you need to write this in native code. If you write your code in java, your app will be uninstalled before it could execute any code.
please see this demo : https://github.com/sevenler/Uninstall_Statics
Google C2DM service is working in passive mode when it comes to detecting uninstalled applications.
First push notification after uninstalling your application (without unregistering from C2DM!!!) will NOT return any error in response. However, the second push notification will return an "invalid registration" or "not registered" error codes where you can realize the application was uninstalled.
The reason is that C2DM servers return the response code immediately and only then tries to push the client. When client respond that an application was uninstalled, it is deleted from C2DM servers. Next push attempt will return an error code immediately.
I have some points to tell you ,
Android community recommends you to use GCM instead of C2DM as it's no longer available.
In android there is no way for applications to get itself notified that app is getting uninstalled.
in GCM if you want to stop sending messages to uninstalled apps you can refer this
When you send messages to GCM from your server you will get response string.In that if you are getting error as "NotRegistered, you should remove the registration ID from your server database because the application was uninstalled from the device or it does not have a broadcast receiver configured to receive com.google.android.c2dm.intent.RECEIVE intents."
I know only one way with server response 200 with "NotRegistered" message in body.
NotRegistered — The registration_id is no longer valid, for example user has uninstalled the application or turned off notifications. Sender should stop sending messages to this device.
Look into this GCM doc:
GCM Unregistration
You should never unregister your app. This is taken care from server side.
To detect app uninstallation using Google Play Services, you can use the App Uninstallation Reporting API. This API allows you to receive notifications when your app is uninstalled by users. #ThanksChatGPT
I am trying to implement push notifications in Unity Android, I've completed the Quick Start and have done everything I can find out to do, but when I try to do a test push using the "Test" button on the Quick Start page, I get the message "Can't find any registered devices yet...". No errors or messages appear in the Parse logs, just this on the Quick Start page itself just below the "Test" button.
I have installations in the "Installation" table. I've even added code to my app to subscribe to channels (I've tried various names, as well as an empty string ""), and these subscriptions appear in the Installation table for those installation records.
When I go to initiate a push from the Push page on the dashboard, it correctly lists the number of devices that will be targeted by the push, but none of my devices receive anything, and it shows that 0 pushes were sent. And I keep receiving the "Can't find any registered devices yet..." message on the Quick Start page.
I even tried building the Push sample app, found some things wrong with it which prevented it from even running on the device, but I cannot get it to even register an installation, much less receive a push notification.
I have been working on this for over a week now, and I'm desperate for some help. I really need to know the reasons why Parse would be reporting there are no registered devices despite the presence of installations.
Details:
Parse 1.6.0
Unity 5.1.0.f3
When the user uninstalls the app from his android device, it means that the registration_id for C2DM is no more valid. Now, how does the server which sends the push notifications know this. With Apple, there is something called Apple-feedback which lists out all the device-tokens (Android folks, read as registration-id) that are invalid.
Please, help me out with this.
I'm also looking for a sollution to this, so far I've only found one useful sollution which is mentioned here: http://groups.google.com/group/android-c2dm/browse_thread/thread/8e58ed95a0818716
In short: When you SEND the message to the device, send an UID with it (eg. generated on first install). When a message is received in the application, check if the UID is the same, if it is, do you thing (eg create notification), otherwise ignore it, and send a msg to your C2DM server that this Google C2DM registration ID is not valid anymore.
I think that is the reason C2DM are refreshing the Registration ID after random time. If user uninstall the App from his device, he is not not going to update his/her Registration ID either. Then he will not getting any Push Notifications anymore.
My app is using Google's C2DM (push notification) to notify users about new activity from friends. Once they install the app I register the device with C2DM servers and store user's phone number. So I know that the user is using my app and I can send him/her the push notifications. But what happens if users uninstalls my app, is there a way to catch it in my app? Or the only way is to catch an error on my server when I send a C2DM and it's unreachable, then mark a user as inactive?
I would love to notify users when their friends are using an app and when they no longer do.
What's is the best solution for this scenario?
The GCM documentation explains this situation here:
https://developers.google.com/cloud-messaging/registration#how-uninstalled-client-app-unregistration-works
"An application can be automatically unregistered after it is uninstalled from the device. However, this process does not happens right away, as Android does not provide an uninstall callback."
Basically when GCM tries to send the next push notification, the device will tell GCM the receiving application was uninstalled.
As for notifying friends that their friends aren't using the app any more, GCM will send a NotRegistered error to your notification server when this failure occurs; it won't be immediate, but could you use that?
Unfortunately the ACTION_PACKAGE_REMOVED intent will be sent out to all receivers except for your own. This is confirmed here.
Some questions for your C2DM plan, since I'm not very familiar with it. If the user just leaves their device off for a long period of time, will that trigger the error condition you use? How does C2DM actually report an "unreachable" device? Is that a condition that only occurs when it attempts to send the push notification and fails or is it when it somehow determines it reaches the device but fails to be handled properly? Obviously in the second scenario your plan would work, but I can see some "false positives" occurring otherwise.
Older SO question for reference: android not receiving Intent ACTION_PACKAGE_REMOVED in the removed package
Yes, but it is quite hacky.
The method is based on the fact that the first thing android does when uninstalling your app is deleting your data file. So you could use a file watcher to detect the deletion.
Also you need to write this in native code. If you write your code in java, your app will be uninstalled before it could execute any code.
please see this demo : https://github.com/sevenler/Uninstall_Statics
Google C2DM service is working in passive mode when it comes to detecting uninstalled applications.
First push notification after uninstalling your application (without unregistering from C2DM!!!) will NOT return any error in response. However, the second push notification will return an "invalid registration" or "not registered" error codes where you can realize the application was uninstalled.
The reason is that C2DM servers return the response code immediately and only then tries to push the client. When client respond that an application was uninstalled, it is deleted from C2DM servers. Next push attempt will return an error code immediately.
I have some points to tell you ,
Android community recommends you to use GCM instead of C2DM as it's no longer available.
In android there is no way for applications to get itself notified that app is getting uninstalled.
in GCM if you want to stop sending messages to uninstalled apps you can refer this
When you send messages to GCM from your server you will get response string.In that if you are getting error as "NotRegistered, you should remove the registration ID from your server database because the application was uninstalled from the device or it does not have a broadcast receiver configured to receive com.google.android.c2dm.intent.RECEIVE intents."
I know only one way with server response 200 with "NotRegistered" message in body.
NotRegistered — The registration_id is no longer valid, for example user has uninstalled the application or turned off notifications. Sender should stop sending messages to this device.
Look into this GCM doc:
GCM Unregistration
You should never unregister your app. This is taken care from server side.
To detect app uninstallation using Google Play Services, you can use the App Uninstallation Reporting API. This API allows you to receive notifications when your app is uninstalled by users. #ThanksChatGPT