I'm a beginner in fcm and stuck in one issue. After getting reference from several source I'm able to implement it successfully. But now I'm trapped in a strange issue.
As fcm creates unique tokens per device so notifications can be sent to that device using that unique token only . So, after the token is generated I'm saving that token into mongodb for that particular user and the notification is sent to that device without any problem.
Now let's assume a scenario : Let a and b be two users having different device so they'll have unique tokens in their mongodb documents . Now if a will try to logging in into his account from b's device then how can I send notification to a's account in b's device as the mongo-document of a containing token for a's device which can't be used for the current i.e b's device
Please do excuse me if my question is silly.
You need to always make sure you update tokens when a user signs up or logs into a new device. If the user has give permission before, this shouldn't notify the user again and if not, user will be prompted to give permission and you can save the new token then.
It is usually good to keep the tokens in format of an array so you can send notifcation to all the tokens inside that array at any given time, i.e, all the devices that user is logged into.
Here's an example which you can see the token being saved in an array.
Related
I've read all the documents of Firebase messaging,
but in my use case, I don't know how I should implement it...
In my use case :
The User can sign in at multiple devices.
Whenever an user has signed in at the specific device, the device should get notified when the user account receives any event.
This might be a little complex, but please take a look at the three situations below :
Each number of situation:
User A signs in at Device 1, so Device 1 will get notified for User A.
Now User A signs in at Device 2 as well, so both Device 1 and Device 2 should get notified for User A.
Then finally User B signs in at Device 1, so Device 1 no longer get notified for User A, instead, it will get notified for User B now.
The lifetime of the User and the FirebaseInstance Token are different, so how could I make this? (I have a backend server to store the registration Id.)
What's in my brain:
For 1 situation: To simply get the device token and save to the backend database.
For 2 situation: For this situation, I need to create a RegistrationToken table for saving multiple device's token with a relationship with User so that one user can own multiple registration tokens.
For 3 situation: Update the relationship to User B instead of User A if the token exists in the database.
But I think those solutions will be a hard work and uncommon, please tell me how do you solve this problem?
What i will suggest is that when you are registering a new user make a coloum in your database called token to store the firebase device id token
So when the new user register you will get a new token assigned to its username
Then with every login and log out attempts change the firebase id token
This means that when ever someone will login from any device its token will be updated in database and when the user logout just pass null value to it hence you can ensure that users always get the right token according to usernames
Hope it helps...
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'm going to develop an app that uses device groups feature. As I understand I need to first send current registration token I get on Android client in method onTokenRefresh to the server and then add this registration token to proper device group (or create it if it doesn't exist) via HTTP request. I see, however, a potential for leaking registration tokens, as Android app user may for example wipe app's data multiple times. How to prevent it? What happens when a limit of 20 members is exceeded? And is it possible to check whether some group already exists or not?
I see, however, a potential for leaking registration tokens, as Android app user may for example wipe app's data multiple times. How to prevent it?
If by preventing you mean disabling Clear Data for your app in the App Manager, you should refer to this post. The accepted answer states that it isn't possible.
However, Jakar's answer provides a workaround where instead of Clear Data, Manage Spaces will show up instead. Haven't tried it out yet, so I can't say for sure. The upvotes speak for itself though.
But, if ever the app's data is wiped/cleared by the user, you should refer with what is stated in the FirebaseInstanceId docs:
Instance ID is stable except when:
App deletes Instance ID
App is restored on a new device
User uninstalls/reinstall the app
User clears app data
In the above cases a new Instance ID is generated and the application needs to recreate the authorization tokens previously generated implementing onTokenRefresh().
What happens when a limit of 20 members is exceeded?
Not sure what the question is here.. But if you are pertaining to adding devices to a Device Group more than the maximum...
Wasn't able to find it clearly stated in the FCM: Device Group Messaging docs, but if you refer to the Add to group section, it states:
A successful operation returns a notification_key.
So from that, I think if you ever try to add another device to an already maxed out device group, the operation will fail.
I suggest using Topics instead, if you think you're going more than 20. But I don't really know what your use-case is, so.. your call.
And is it possible to check whether some group already exists or not?
For this, you should make use of the notification_key and notification_key_name. As per the docs:
The notification_key_name is a name or identifier (e.g., it can be a username) that is unique to a given group. The notification_key_name and notification_key are unique to a group of registration tokens. It is important that notification_key_name is unique per client app if you have multiple client apps for the same sender ID. This ensures that messages only go to the intended target app.
And emphasizing on the statement:
Basic management of device groups — creating and removing groups, and adding or removing devices — is usually performed via the app server.
The keys and names should be on your server, so that you can check if it already exists or not.
I am currently doing the following with some success but not fully tested or scaled yet.
App uses firebase as the backend and I am adding FCM to implement push notifications.
I need groups to handle when a user could be on different devices or several devices.
I store the returned notification_key value and the registration_id (token) for each device with the profile i.e
profiles
-profile_id
-FCM
-notification_key:value
-registration_ids
-device_1_uuid:token_for_device_1
-device_2_uuid:token_for_device_2
When a user first signs on there is no data under the FCM node i.e. no notification_key and no registration_ids
Each time a user signs in they hook up to their profile_id.
I get the FCM token and then
If there is no notification_key (i.e. first time on any device) I create the group using the profile_id as the notification_key_name and store the notification_key that comes back.
If there is a notification_key (return sign-in or first sign-in on a new device) I see if there is a registration_id for the current device and if not (first sign-in on new device), add the device_uuid:token pair to the registration_ids.
If there is (return sign-on) I remove the stored token from the FCM group and replace the old token in my stored registration_ids with the token I just got.
I can now message all of the devices used by that user (profile) by sending to their profile_id, and I shouldn't be leaking tokens because I delete the old ones.
However, I have no way of knowing because there doesn't seem to be API to just read the group and the tokens so that the groups could be cleaned every now and again.
Also, my early code bugged and I didn't capture the notification_key so now I can't add, remove or do anything to one of my groups. I hate the idea that I'll have to leave burned groups lying around in the firebase cloud for ever and ever.
I think FCM should provide more API access to help us keep the place tidy.
I have developed android where I am using GCM to send notification.
I am facing one problem that i will explain by taking an example.
Let's say user A logging in my app. So I generate token for that user let's say that is "AA1" using GCM and storing it our database. But then if user uninstall app and install it again. Then I am generating token again (Lets say AA2) and storing in our server.
If both tokens are same then it will not cause any issue as I am comparing before inserting a token. But as GCM tokens for same device can differ. Right ?
Later, When I want to send a notification to that user. That user will get notification twice as his previous token is still working. I tried to search but found nothing related to this. It may that I am missing something or none have thought like this.
Doesn't matter which but I think there must a way to solve this issue.
Question
Is there a way to check both the notification tokens belongs to same device or not?
Is there a way to remove notification token from our database when user uninstall apps ?
Please guide me.
What i think is this problem can be solved this way.
When you are storing Token value to application server, you should map it with users device id. therefore when this token is re-generated (with different value), your application server can update the token for that user as in both cases device id was same.
Is there a way to check both the notification tokens belongs to same device or not?
Not in a unique way. You could make an IP comparison when the user registers and store both the GCM id and their IP address, this way when they connect again you can check whether you already have a registration with that IP address and delete the previous. However, this is not a good 100% solution as there are countries that assign the same IP address to several devices. I think the best approach here is implementing a timeout mechanism. In my apps, when the user registers, they have to send a "keepalive" HTTP POST signal every 30 seconds to say "hey, I'm still here". If that keepalive doesn't arrive in a reasonable amount of time, I consider it a timeout and remove it from the database.
This is, however (now I mean unistallation), one of the cases where you should call the GoogleCloudMessaging.unregister() method and send it also to the third-party server.
Is there a way to remove notification token from our database when user uninstall apps ?
Seems that there's not (Perform a task on uninstall in android). But however, with the above approach, you wouldn't have any further issues as this user would stop sending the "keepalive" notifications and he would be timed-out.
Agree with you. But still there is a solution. what you can do is, you can use device IMEI number as device id and use it. This IMEI number will never change even if on factory reset.
How to get unique device hardware id in Android?
TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
telephonyManager.getDeviceId();
Also add the below manifest permission.
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
What we do is generate a unique ID (in our server) for each application instance. The application gets that ID by making an API call after first being installed on the device. We store that ID in external storage (that doesn't get wiped when the app is uninstalled). The registration ID of the device is associated in our DB with our unique ID.
This way, when the app is installed again on the same device, we get that identifier from the external storage (if available) and re-use it, and even if the registration ID is changed, we know it belongs to the same device.
In addition to this strategy, your server should handle the following scenarios :
If you get a canonical registration ID in the response from GCM, delete the old registration ID (if the canonical ID already exists in your DB) or change it to the new canonical ID. This would prevent duplicate messages from being sent again to this device.
If you get NotRegistered error in the response from GCM, delete the registration ID you attempted to send from the DB. This means the application was uninstalled. There is no other way to detect that the user uninstalled the app.
One Solution I think would be to send a pushnotification key with every notification. Handle this on your client side by keeping a last pushnotification key used in shared prefs. If you get the same notification key again drop it.