I am implementing push notification in my app after having it for IOS for a while.
Use case: I have user login, and accounts stored on our servers. I only want to send push notifications when a user is logged in, and only for the user currently logged in. Notifications are targeted to the individual user.
To do this, i fetch the token using
FirebaseInstanceId.getInstance().getToken()
, send push token to our server when user logs in, and remove it on logout.
Everything works as far as registering token, sending the token etc., HOWEVER, there could be scenarios where this doesn't work, for example if a user logs out with flight mode, so our server still has the token and thinks it should still send them.
On IOS, there are two local functions, register/unregisterforremotenotifications, that basically turns notifications on/off, regardless of whether my server could be contacted. I can call these on login/logout, and IOS won't show any remote notifications for my app, and i'm safe.
However, with Firebase, i can send the token to the server on login -
for logout, however, its more complex since there's no "local" system-function to call that i can find.
The best thing i've figured out, is to always send a 'Data' notification,
as described in this question,
so that my notification service always gets called, even in the background, and there check if i am logged in, and not show the notification if i'm not.
However, the notification for the wrong user will still be sent to the phone, and it's a risk, for example if i, god forbid would have a bug... or the notification gets logged somewhere in the system.
Sooo, my question is if there's any way to disable notifications on logout via Firebase?
I hope this makes sense, thoughts much appreciated!
Yes, what you do is you create your own Login and Logout APIs.
In your Login you should be storing your Token for PUSH notifications.
then whatever data triggers need to PUSH do a loop and build a push for known registered tokens.
On logout, simply delete that token from your Database and the loop will no longer include it for PUSH. You are correct using DATA tag will only work in foreground, but could be for wrong user that is correct.
If you do not have a backend, then please provide more clarity as to where/how you are storing and using your tokens to PUSH so I can help you further.
I have done this exact scenario to avoid wrong person getting push, but I support foreground and background on my scenario, so only logout or expired token will disable the PUSH on my app.
There are two ways:-
Your app supports multi user login at the same time scenarios :-
You can probably store the device token in share preferences with a boolean flag , when user relaunch the app , check if the flag for deletion is set then you can try deregistering from the service on server.
If it fails then again you can do the same , so it would be something like checking boolean flag for account deletion on every app launch to make sure it deregister.
Your app supports single usr:-
You can simply delete firebase instance Id before signing into the account. This would take care of the scenario where a different user had signed out offline and you were not able to de register from your service.
You can also handle scenarios when to show notification based on accountId or user Id of the signed in user.
Related
So, I just want to handle the situation when user logs out from the app.
I call method FirebaseMessaging.getInstance().deleteToken() when user logs out, and it works as expected, i.e. user doesn't receive push messages anymore...
But if there is no internet connection method deleteToken() doesn't help. User still gets push messages when a connection is established despite the fact that he logged out.
How can I handle this?
Firebase Cloud Messaging has no knowledge of the user, which explains why it can't change whether it sends/displays a message based on authentication status.
The main problem here is that notification messages are displayed by the system if the app is not being used, and you can't control what the system does with them based on authentication state.
The best way to deal with these situations is to only send data messages (without a notification property). The display of such data-only messages is handled by your application code, so your application code can check whether a user is signed-in, and decide whether to display the message based on that.
I also recommend reading up on FCM messages types to learn more about the distinction between these types.
I know this has been discussed before, but the only solution I found (canonical IDs) don't work in my scenario.
Scenario:
User installs App and registers with his user account A
User gets push notifications meant to be delivered to this specific user account A
User uninstalls the app
User reinstalls the app
User registers with a different user account B
Now notifications are delivered for both user accounts. From my understanding, using cannonical GCM Reg IDs would only consolidate those IDs and prevent sending duplicate notifications. In this case the App gets notifications for a different user that shouldn't be delivered at all.
Is there any fix for that? Only thing I can think of would be actively deregistering when uninstalling the app, but in another thread I read, it's not possible to execute code on deinstallation.
From my understanding, using cannonical GCM Reg IDs would only consolidate those IDs and prevent sending duplicate notifications.
That's one way of looking at it, but on a simpler note, Canonical IDs are like saying "old ID you used is expired, delete it (if you saved it) and use me instead".
The thing that makes this a bit odd is that, when the user uninstalls the app, the InstanceID should be invalidated. (see the docs here).
What I think you can do to make sure that tokens are deleted, you can call deleteInstanceId() to revoke all tokens, then re-register.
But to make sure that the message is for the intended user, you can refer to what is stated in the docs (first one similar to what #Ak9637 said):
To make sure that messages go to the intended user:
The app server can maintain a mapping between the current user and the registration token.
The client app can then check to ensure that messages it receives match the logged in user.
You can simply check ,when registering in your tokens database,when u receive token of user B , just check if it is already associated with any user or not, if it is simply nullify that field and save the new token to new user.
As token identifies the device not the user.
If you wish to take total autonomy and control of notifications related to your app, You should use data notifications instead of message notifications , this will avoid the OS handling the notifications instead of your app
i have an cordova App , when user login new "app registrationId" is sent to server and is saved in database for further use (when app user receive a message from someone else ) , however when user logout i want to clear all pending message in gcm , so that if another user login he doesn't receive Previous user notifications.
is there any way to do this in GCM ? or my scenario is totally wrong !?
thanks.
A registration token corresponds to a single app instance (tied to the device) and not to a single user specifically.
I've also searched around about this topic before and the usual solution is for you to have a user identifier included in your payload, let's say a userid. Then in your client app, you must check if the userid matches the one who is currently logged-in. If true, show the notification, else, disregard the message.
With this, if a different user is logged-in and a push was sent to that specific registration token, your app will handle it and will not show any details not for the corresponding user.
However, this means that only if the original user is logged-in will your app be showing a notification.
Anyways, it's still a valid workaround for the behavior you're aiming for. Hope that makes sense. Cheers!
I want to store FCM token in my android app user's table in database when user register to the app . When i want to send notification to specific user then i will fetch Token from corresponding row and send push notification.But i am confused that whenever app user logout from his app and register new account from same device ,then there will be two row and hence two Token for same device on database. How to handle such case? What happen to old Token in device? please anyone can help me??
The Instance ID token used to send FCM messages represents the instance of and app on a device. The current user of the app would not affect the token that represents the app instance. Uninstalling and reinstalling the app would cause a new token to be generated but not for in app behaviour like switching users.
You should still remove the mapping of the token to the user on logout and add a new mapping with the same token to the user that logs in but it will be the same token.
I probably feel this may help you,
When user logs out clear his device token and make him Logout so that he won't be able to receive the updates and hence only one user at a time can get the updates
Should I make the call each time a user enters the main activity or should I only make it when the user first installs the app?
startService(new Intent(this, RegistrationIntentService.class))
Essentially the RegistartionIntentService will do the same action (register your app to google's SNS server using the token your app acquired) so it's pretty much usless to do it every time, I'd say you should do it only once after the first time the app has opened.
In order to send push notifications to a device, you need the registration token that is generated by your app when you run your registration service. What you do with that token after you register the device is up to you.
What I do is, when my user logs into my app, I run my GCM registration service which for me, generates a token and then sends that token (along with the logged in user information) to my backend database. From that point forward, my backend code knows the user has registered their device and whenever I need to send them a push, I know to send it with that token.
When the user logs out, I once again make an API call to my backend database which deletes the GCM registration token (you don't have to but its how I do it.)
The point is, once you get that token with your registration service, what you do with it is your responsibility. Save it, store it, etc. You only need to get it once - then you can send all the pushes you want.