Android: Delete record from remote database on app uninstall - android

I have written an application (AirQApp) for general public as well as for our customers. When customers log in with the given username and password, it stores the device registration ID in the central database to generate gcm notifications for the specific customer similarly when they logout it deletes the device ID, but when they uninstall this application, it cannot delete the device ID from the database hence notifications are still generated.
I googled it and it seems like it is not possible to perform a task on application uninstall.
Is there any other solution which can be applicable in my scenario?
Is there any way to check if the application is installed on a particular device from device registration ID?
Thanks in advance.

The end user uninstalls the application.
The 3rd-party server sends a message to GCM server.
The GCM server sends the message to the device.
The GCM client receives the message and queries Package Manager about whether there are broadcast receivers configured to receive it,
which returns false.
The GCM client informs the GCM server that the application was uninstalled.
The GCM server marks the registration ID for deletion.
The 3rd-party server sends a message to GCM.
The GCM returns a NotRegistered error message to the 3rd-party server.
The 3rd-party deletes the registration ID.
From Here

I googled it and it seems like it is not possible to perform a task on application uninstall
Correct.
Is there any other solution which can be applicable in my scenario?
The next time you try to send a message to that GCM registration ID, GCM should tell you that it is no longer registered.

Related

GCM: Handling Old RegistrationId when user uninstall the app

Here is the scenario of the problem I am facing right now. I have a web app that holds all the registration id of devices that connected to my server. On my android app. Every time the user logs in, I send request for registration id to google, forward to my server, then the server saves it and link it to the user. When a user logs out from my app. My app sends a request to the server to destroy the authentication code and registration id. The problem was, when the user uninstalls the app and a reinstall it again, his old registration id retains on my server. So when he logged in on his same phone. the app registers the new registration id to my server, when the server pushes a notification, that user would receive multiple notification depending on how many times he uninstalled the app. What is your work around on this one?
From the Official Documentation:
A client app can be automatically unregistered after it is
uninstalled. However, this process does not happen immediately. What
happens in this scenario is:
The end user uninstalls the client app.
The app server sends a message to GCM connection server.
The GCM connection server sends the message to the GCM client on the device.
The GCM client on the device receives
the message and detects that the client app has been uninstalled; the
detection details depend on the platform on which the client app is running.
The GCM client on the device informs the GCM connection server that the client app was uninstalled.
The GCM connection server marks the registration token for deletion.
The app server sends a message to GCM. The GCM returns a NotRegistered error message to the app server.
The app server should delete the registration token.
Note that it might take a while for the registration token to be completely
removed from GCM. Thus it is possible that messages sent during step 7
above get a valid message ID as a response, even though the message
will not be delivered to the client app. Eventually, the registration
token will be removed and the server will get a NotRegistered error,
without any further action being required from the app server.
Check this our: Downstream messages response codes
Unregistered Device
200 + error:NotRegistered
An existing registration token may cease to be valid in a number of scenarios, including:
If the client app unregisters with FCM.
If the client app is automatically unregistered, which can happen if
the user uninstalls the application. For example, on iOS, if the APNS
Feedback Service reported the APNS token as invalid.
If the registration token expires (for example, Google might decide
to refresh registration tokens, or the APNS token has expired for iOS
devices).
If the client app is updated but the new version is not configured to
receive messages.
For all these cases, remove this registration token from the app server and stop using it to send messages.
Refer Official document.
You have to check this on your server. You cannot do it from the application code since there is no way of knowing when the user is uninstalling the application.
when you send a push notification, GCM will check if the user has your application, if the user has uninstalled the application GCM will note the same and inform you as part of reply for the push.
EDIT - From GCM docs
How uninstalled client app unregistration works
A client app can be automatically unregistered after it is
uninstalled. However, this process does not happen immediately. What
happens in this scenario is:
The end user uninstalls the client app.
The app server sends a message to GCM connection server.
The GCM connection server sends the message to the GCM client on the device.
The GCM client on the device receives the message and detects that the client app has been uninstalled; the detection details depend on
the platform on which the client app is running.
The GCM client on the device informs the GCM connection server that the client app was uninstalled.
The GCM connection server marks the registration token for deletion.
The app server sends a message to GCM.
The GCM returns a NotRegistered error message to the app server.
The app server should delete the registration token.
Note that it might take a while for the registration token to be
completely removed from GCM. Thus it is possible that messages sent
during step 7 above get a valid message ID as a response, even though
the message will not be delivered to the client app. Eventually, the
registration token will be removed and the server will get a
NotRegistered error, without any further action being required from
the app server.
This can be done on your server side code.
While inserting requested data to your GCM table, check if your user id is already in table? if yes simply replace whole row with new data. else insert fresh new data into table.
Side-note : it is better practice to check for duplicate GCM registration id as well. because google refresh all GCM ids frequently.
Hope this will help.
EDIT
as #Haunter suggested,
what if the users have a multiple devices?
Well in this case use store IMEI number on your database and check for that instead of user id.
how to get IMEI number
TelephonyManager tel = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
String IMEI = tel.getDeviceId().toString();
Some changes on my code: (Might help someone)
I have remove IMEI to avoid issues. In order for the server to validate all users registration id to be valid, even he/she reinstalls the app. When an android device registers it new registration id on the server. After saving the new registration id,server will run a worker, starts gathering all the registration id of the current user,then send a dummy notification (empty string) on each registration id, when gcm respond with a canonical Id > 0 or an error like NotRegistered, I then delete the registration id,

Should I generate android GCM registration ID app specific or user specific?

I am developing an app which has login functionality.I am generating only one gcm registration ID per app. If other user sign's in in same app he will start receiving notifications intended for the previous user.
How to handle this situation, so that each user will get notification intended for his/her?
Should I generate gcm reg id for each user?
What is the standard way to handle this situation?
You could try the following things:
When the user logs off, send a request to delete the token on your server, and erase it on your app;
Once the user logs off, you could simply remove the association of "User ID" to "GCM Token" (Or Registration ID) on your server. And when someone logs in again, you make a new association to that Token.
The GCM Token is app specific, but the association you make on your server is totally up to you.
And I can't stress it enough, the token generated by GCM is APP SPECIFIC. If your user logs in on multiple devices, your server should handle that, associating the user ID to multiple Registration ID Tokens.
An ID issued by the GCM servers to the Android application that allows
it to receive messages. Once the Android application has the
registration ID, it sends it to the 3rd-party application server,
which uses it to identify each device that has registered to receive
messages for a given Android application. In other words, a
registration ID is tied to a particular Android application running on
a particular device.
And from the docs, your server should also:
Before you can write client apps that use GCM, you must have an
application server that meets the following criteria:
Able to communicate with your client.
Able to send properly formatted requests to the GCM connection server.
Able to handle requests and resend them using exponential back-off.
Able to store the API key and client registration tokens.
Able to generate message IDs to uniquely identify each message it sends. Message IDs should be unique per sender ID.
EDIT: You can read more about GCM here.
For further reading, you could also read more on Device Group Messaging.
You can also download some code samples here.
You should store regID as per user.
This is because there is test cases that user1 logs out and user2 logs in. In that case if you have stored regID app specific and not binding with user then user2 will also get notification.
So you need to store regID as per user , app and as well as device specific.
Of course yes every time someone downloads your app, your app should register them with the GCM and be given a reg token, this needs to be sent to your app server, on your app server you need to sort out who you are sending the notification too. you should probably send some login info and reg token when they login so you can identify each person, then write some php or Jquery to send to individual users or all. you should also send the reg token every time they login as these can change without warning.
Your app server should be able to handle removing unused reg tokens and adding new ones
Each android device generate a Unique GCM reg id. push notification from server side will send according to the device id. So at Login time you can send GCM reg id to your server. So from server side push notification will send to device.., that is actual functionality.
Hope this will help

App receives duplicate notification using GCM after reinstalling [duplicate]

This question already has answers here:
Do old GCM tokens live on even after an uninstall?
(2 answers)
Closed 7 years ago.
I'm currently trying to use GCM to send notification to user and currently I'm still studying on how I can maximize it. For now I just use the sample project provided on the documentation here and I use the gcm-client sample to work on it.
Now using this project from Git I tried to push a message using the registration ID created by the app and yes it successfully delivers the message.
Now the problem is that after I uninstalled the application. After I reinstall it it will generate a new registration ID wherein I store it on a server together with the previous one except that I can't tag the previous registration ID to not receive any further message since the uninstall might happen when user has no internet connection. After that I send a message to two registration ID's which is the ID before uninstalling the app and the ID after reinstalling the application. What happen is that I receive two push messages eventhough I expected it to only get one since the app already changes the registration ID.
I expect that the app might receive twoor more duplicate apps if ever I also updated the app since as said on documentation the registration ID might change on update.
Any workaround I can do to handle this duplicate messages?
From the official documentation:
How uninstalled client app unregistration works
A client app can be automatically unregistered after it is
uninstalled. However, this process does not happen immediately. What
happens in this scenario is:
The end user uninstalls the client app.
The app server sends a message to GCM connection server.
The GCM connection server sends the message to the GCM client on the device.
The GCM client on the device receives the message and detects that the client app has been uninstalled; the detection details depend on the platform on which the client app is running.
The GCM client on the device informs the GCM connection
server that the client app was uninstalled.
The GCM connection server
marks the registration token for deletion.
The app server sends a
message to GCM.
The GCM returns a NotRegistered error message to the
app server.
The app server should delete the registration token.
Note
that it might take a while for the registration token to be completely
removed from GCM. Thus it is possible that messages sent during step 7
above get a valid message ID as a response, even though the message
will not be delivered to the client app. Eventually, the registration
token will be removed and the server will get a NotRegistered error,
without any further action being required from the app server.
However, it can apparently happen that you still get the notification for the old registration ID, as users state in other questions:
Android GCM and multiple tokens
Unregistering and re-registering for GCM messages causes two regId's to be valid. Is this as intended?
Do old GCM tokens live on even after an uninstall?
For this problem, there is a functionality called "canonical IDs":
Canonical IDs
If a bug in the client app triggers multiple registrations for the
same device, it can be hard to reconcile state and the client app
might end up with duplicate messages.
Implementing canonical IDs can help you more easily recover from these
situations. A canonical registration ID is the registration token of
the last registration requested by the client app. This is the ID
that the server should use when sending messages to the device.
If you try to send a message using an old registration token, GCM will
process the request as usual, but it will include the canonical ID in
the registration_id field of the response. Make sure to replace the
registration token stored in your server with this canonical ID, as
eventually the old registration token will stop working.
#KaHel When client app was uninstalled regId will be valid during some time, you are right. But, when client app will be installed again and your push server try to send message on old reg id that message will be successfully sent but GCM server put cannonical_id in response. And you should correct processes this response with cannonical_id. How do this i described at this post and there is not big documentation about cannonical_id. I.e. as soon as you get cannonical_id from GCM server you should immediately replace old reg_id by new one value. It will allow you not to produce a many regIds for one client, just one to one.
After reinstal you will get new RegId and prev not valid anymore. So, even if you send push to both RegIds, only last will received it.
You can implement logic for accounts in application.
For example, when user login in application you send his GoogleId + RegId. After reinstall of application and relogin you just update RegId on server. So, you can have only one RegId for every user.
There is problem: only one device will receive push msg (if you login in 2 devices with same account). So, you can send to server GoogleId + RegId + DeviceId after start application.

Send gcm message to only installed user

I want to send gcm mesage to only installed user or devices.
Active (installed) user is only 20% of gcm-registerred users in my app.
Maybe 7~80% is delete my app.
I want to send ony installed users, not uninsatlled user.
It is possible to send to only installed users? or to get event that user uninstall my app?
Send your message to all users. If a user has uninstalled the app, GCM will notify you in reply to your push message. You can then remove those users from the database.
You can see a description of this process here
The end user uninstalls the application.
The 3rd-party server sends a message to GCM server.
The GCM server sends the message to the device.
The GCM client receives the message and queries Package Manager about whether there are
broadcast receivers configured to receive it, which returns false.
The GCM client informs the GCM server that the application was uninstalled.
The GCM server marks the registration ID for deletion.
The 3rd-party server sends a message to GCM.
The GCM returns a NotRegistered error message to the 3rd-party server.
The 3rd-party deletes the registration ID.
if you send gcm message then only install user get this any user who have alredy uninstall your app not get nofication dear
try to send to all user its not an problem

Android C2DM : Duplicate message to the same device and App

I'm wondering if anyone has faced this issue with Google C2DM? This is the scenario I am faced with:
User installs the app and registers
with C2DM server for a registration
key.
User uninstalls the app.
User reinstalls the app (and
registers with C2DM server for new
registration key).
Now I send message from my server to the user's phone and they get a duplicate message.
Could anyone shed any insight into wether this is expected behaviour or how I can fix it?
Thanks,
Not sure if this is the best approach, but there's a relevant thread over at the android-c2dm group, where the poster offers one technique:
I am sending registration id in the message, so I can check it against the stored registration id on the device.
If it's not the same, discard it and notify the service that registration Id is no longer in use
Downside is sending registration Id takes up some space in already
limited message size. But works perfectly in my case since my
original message is no more than a few chars long.
This should only happen for the first push notification after re-installing your application.
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.
Another solution could be to provide your server with a unique identifier for the device. In that case you can just update the registrationID for that UUID when the device tries to register after re-installation.
Yup, I've run into the same issue and in my opinion it's a big oversight in the Android C2DM implementation. iOS handles this much better in that an app can only ever receive notifications for one and only one device token (equivalent of the c2dm registration id)
The workaround I use is to send the last 10 characters of the registration id as part of the c2dm payload and then in my onMessage method I do the following check:
if (!regId.endsWith(bundle.getString("regsuffix"))) return null;
Both #Zamel and #johan answers are good and need to be combined. If you combine both solutions than you will minimize your server's database.
So the best solution will be to:
Send device id when sending the push token to the server
Update push token when is sent for existing device id
Invalidate push token in the server's database, if push notification returns an "invalid registration" or "not registered" error codes to the server
When push token is recognized as "invalid registration" or "not registered" you can invalidate it(mark it as null), delete the row in the database or implement expiration functionality. It depends on your needs

Categories

Resources