I have a android client app, a server side in django and now I am adding push notifications with GCM.
In my app I have users that login/logout, so I will have a table in my database with devices ids coupled with users, so that every time I want to notification a user, I will lookup its device id and send the notification.
my question is:
When is best to register the Device to the GCM?
When to add the Device to my Server side database?
In the Google Docs it says you should do it once, when the app is installed.
Because I have users in my app, and I want to couple a user with a device in the database, when the app is installed there still isn't a user to associate the Device with.
After the user installs the app, he can register, login and so on.
So when you think is best to register the Device to the GCM and to my server side?
Should it be with a user or only associate it later?
Thanks a lot!
My suggestion would be:
Register the device immediately after the first execution
Save device id somewhere accessible anytime by the app
Couple the id with user details after registration
With this approach you will be able to handle issues if something goes wrong with the registration process and send a notification to the device even if the user is not registered.
EDIT:
You should also implement a strategy to check on a regular basis if the association between the user and the device is still valid or needs to be updated
Related
I have some doubts about implementing Firebase Cloud Messaging in my app.
My app is a chat similar to whatsapp and facebook messenger. Right now every time someone logs in I register the token and relate it to the user. So if someone wants to chat to an user the app searches the Db for the user ID and there I have his token.
I'm able to register the device token but I'm not sure when should I do that.
In my chat users register through a mail/password signup and is possible that an user could login in other device.
For example:
User Frehley uses a Galaxy 8 and is able to chat and receive notifications in his device using the token. But lets say that he loges in another device. I need to register the token again and relate it to him right?
So, maybe I'm wrong but the best moment to register the token is every time the user logs in and replace it in the DB. Right?
Now, lets say two users (Frehley and Stanley) uses the same Galaxy 8 to login, the token will be diferent everytime the login or it is the same for every single device?
This all depends on the use-case:
If the same user is logged in to two devices, do you want them to receive the notification on both devices? If so, you'll need to store multiple device tokens per user and send the notification to each token for the targeted user. You could also use a device group to identify the devices for a single user. From those docs:
With device group messaging, you can send a single message to multiple instances of an app running on devices belonging to a group. Typically, "group" refers a set of different devices that belong to a single user
If you want the user to only receive the notification on the device that they were last using, you'll have to associate a single token with each user and overwrite that when they start the app on a device. Not that this is not necessarily when they log in, but more likely when the app detects that they're authenticated.
If a different user uses the same app on the same device (using the same device profile), you probably want to stop sending to the device token. The most robust way to do this is to remove the association between the previous user and the token, but that may require that you keep a mapping from token to UID. An easier way is to delete the device token when a user signs out. Then the new user signs in, they will then get a new token.
I'm working on a new app and I want to give the possibility to my user to use more then one device.
The app can receive push notification, my question is how to save more device/token for each user, this for send push notification to all the user's devices.
My idea is to retrive "some device ID" and then store a id/token for each device but I don't know which device ID I can use...
Another idea is to create a random id the first time and then send this id with token, this work (partially) until the user clear application data...in this case I need to resend a new id (no problem) but I can't know if I can remove the old id/token
any solution?
You don't need "some device ID"; the push token is the device ID. You need to ensure that your backend database can associate more than one push token with a given user account. This is typically through a one->many relationship between user "users" table and your "installations" table.
You can't rely on your app to tell your backend to remove an old token, since the user may simply delete your app and it doesn't get a chance to communicate with your back-end.
The APNS service will deliver feedback as to which push tokens were invalid (I assume that the equivalent Android service also has something like this). You use this feedback to purge invalid installations from your installations table.
I am learning how to implement the GCM both from client side (Android) and from server side (ASP.NET). I spent a bit of time on reading the whole google documentation related to GCM and I also tried the sample that they provided.
Because I need to integrate the GCM in an already existing app, I would like to know some specific stuff.
As I got it, the registration id is a token which ties the app on a specific device to the GCM service and the app server; so, the backend can send downstream messages directly to that device.
In my scenario, I could have multiple users who can use the app on the same device, that means they need to login in the app and they have an account on a database in the server side. Do I need to store a different registration id for each user on that device? Or still the registration id refers to only the app?
And what about the same scenario but distributed on multiple device, because a user can have multiple devices?
Thanks in advance.
This relates a lot to the context of your app and what you want to do with notifications
Having one registration ID per device will be okay.
I manage my multiple users by using subscription tags handled by my server.
So take the scenario if you have a sports app:
User A & User B share the same device. Each user subscribes to a tag.
User A is subscribed to two tags (Basketball & Football)
User B is subscribed to two tags (Tennis & Basketball)
When User A logs out you clear the tags associated with that user and when User B logs in you fetch his/her tags.
Your server knows notifications to send to the device based on the tags the user has subscribed for.
Multiple device scenario:
The same goes, when your user logs In you get their tags. The device also has its own token from GCM.
The registration id is the app's id, it may be changed if app version was updated. Your push notification will be sent on device with your app, regardless user account. So every user on every device will receive your notification, you must store only one refistration id per device.
For multiple users: If your messages are user specific, you would want to retrieve the user's token and subscribe to it only while they are logged in. When you switch users remove/unregister the previous token, then save/register the new user's token.
You should not only do this if you have multiple users per device, but when a user signs out. This will prevent user-specific messages being shown at wrong times to wrong users.
For multiple devices: it sounds like you are looking for Device Group Messaging.
With device group messaging, app servers can send a single message to multiple instance of an app running on devices belonging to a group. Typically, "group" refers a set of different devices that belong to a single user.
This is also nice because of the collapse_key. When one of the devices on the same account opens a notification, it will dismiss the notification on the other devices..
we are implementing c2dm to push notifications to users. we want the user to be able to "opt-out" at the beginning. if they opt-in, then we register the device and send the id to our server to store for later delivery and track that by some unique device id.
the problem is that there doesn't seem a reliable way in android to get a device id. everything i've read says, "just generate a guid at first startup of the app". well, this is fine, but if a user starts up the app, opts in, then uninstalls and re-installs the app, then opts out, i have no way of removing that old device (since the device id of the second install is new).
i've tested and an old c2dm registration id works even after an uninstall and re-install.
any suggestions? how do others allow users to opt-out of notifications. how do you track their devices?
Having a Device ID is nice, but you don't need it to handle opt-outs. When you send a C2DM message from your server, include the registration ID. Then, when the device receives a message, it can compare the delivered registration ID with what it thinks its registration ID is.
If it matches, show the notification. If it doesn't match, ping your server and tell it to opt-out that registration ID.
On first run of your app, you could ask the user whether or not they would like to receive C2DM messages, and send that answer to your server. Then it follows that you would only send C2DM messages to devices that want them.
Instead of a GUID, I would look into getting their associated Android Market account (i.e. email address). This way, reinstalls won't change anything assuming they're using the same Android Market account.
I just added C2DM capability to my Android App.
At the moment the following happens if C2DM is started in my App.
My App sends the registration Intent
The answer broadcast is received by my app
The device token is retrieved from the intent and sent to my server
From that moment everything is working fine. The client receives the push notifications etc.
A problem occurs if the following hapens:
The user uninstalls the application without disabling push. (Completely deleting it not only updating)
The user reinstalls the application
If after step 5 a push notification is sent my app still receives this notification.
It seems that the token which was retrieved from the previous install is still active and is reconnected to the new instance of my application.
This leeds to the following problem:
A user who reinstalls my app but has no intention of receiving push notifications has no possibility to remove himself from the service because the new instance of the app has no way to unregister the old token from my server.
Is this a bug in the C2DM system or is something wrong in my setup?
Update
I followed Berdons advice and did the following:
For testing purposes only start an unregister Intent every time my app starts up.
After I send the unregister intent no push notification from my server is sent to my application. That seems to do the trick, but if I now go the C2DM Settings Screen and turn on push notifications for my app all the old tokens get active again and I receive information that I did not register for in the current installation of my app.
Next Update
It seems I'm not the only one with this problem:
Android C2DM : Duplicate message to the same device and App
I hoped that Google would manage those tokens in a way that old tokens from the same device get disabled after a new one was issued. I also expect that after I sent an unregister Intent all tokens for that application and that device are marked as invalid or deleted from the Google Server for ever. If this is somehow a design decision by Google for special use cases I don't see please enlighten me.
We now found a solution that should work in most of the cases.
The server adds the C2DM registration id as a data field with every C2D Message.
The device now only shows a notification if the token in the message and the token that is stored in a pref file match. That way we guarantee that we don't show messages for device tokens that were obtained by previous installs.
If the tokens do not match we found an old token that should not be active anymore. We now mark the token on our own web server as inactive to prevent the server from sending more unnecessary C2D Messages
This solution enables us to show only relevant data without the need to store a unique user id.
In my C2DM implementation, each user's device token is saved in a database against their UDID and the package name of the app (among other things). The UDID and package name form the primary key, meaning that the table can list multiple apps from the same device (UDID). When a user runs a particular app, the device token is recorded, and if they uninstall and re-run the app, the new device token would be recorded over the old one. We also have columns to record whether push is active for that particular app/device combo, and which types of push messages the user has enabled/disabled.
When the time comes to send a push for a particular app, no UDID will be registered more than once (since these two fields form the primary key), and therefore only the latest device token will be used. Furthermore, our query only returns the rows that have push messages enabled.
This solution should solve your problem because it prevents you from sending the push to both device tokens. I hope this helps!
More like an unexpected "feature". You might consider issuing an unregister request on the "first run" (first run ever) of your application to prevent this from occuring.
Update
You could could do the work of differentiating between different C2DM messages by using the collapse_key (or anything of your own creation) as an identifier. Update it between registrations and pass it to the device following registrations, unregistrations and messages.