When to delete Push subscription from server - push-notification

Just started playing with push notifications and I managed to handle all the subscription process and I'm saving endpoints and keys on my db. My questions is, what strategy should I follow, if any, to delete old subcription details from the database?.
So, if someone allowed notifications and they revoke the permission how do I know who did it to remove the details from the database?. Because if the user unsubscribes I'll just get a null subscription from pushManager.

For Pushpad we use these two strategies:
when a user revokes the permission the requests made using that endpoint will return 410 Gone and you should delete the endpoint
a developer can optionally trigger an unsubscribe with the Javascript SDK that will remove the endpoint from the server (this is useful for example to create a subscribe/unsubscribe button on the website)

Related

Firebase database call working even when Authenticated user is disabled

I use Firebase Firestore and Firebase Authentication in my project.
I am testing out what would happen if I go into firebase console and manually click the "Disable account".
I would expect that if the account is suspended, the authenticated user (test#mail.com in this case) will immediately receive error whenever a Firestore database is called (eg. getDocs(q) or setDoc()). The reason behind this assumption is that I assume Firestore tries to authenticate each call before doing CRUD.
However, after testing out, here is the test and result
Login user (test#mail.com)
Do a db read or write ensure everything works which it does
Go to firebase console and disable the account (test#mail.com).
Try to do another db read or write. The result here is that I was able to still read and write which is not what I expected.
So here are my questions
Is this a normal behavior?
Can I write Firebase security rule to overcome this issue?
It would be less idea if I have to check if user is logged in everytime I do a firestore call. But if that is what I have to do, how can I do that. I believe getAuth()and onAuthStateChanged is not really suitable in this case. Reason being getAuth() seems to only check the database the first time it is called. Any subsequence call it only checks the app memory and do not perform any network request at all (Verified by looking into console network tab). Which is kinda weird. And onAuthStateChanged does not listen to firebase state change, it only listens to if my app logs a user in or out.
Abit of background on what I am trying to achieve
I want to be able to lock a user out from my app by changing something from the db. And ideally not having to PING every few second .
Update:
It seems like it takes about 1-2 hour for my app to automatically recognise that the account has been disabled. It took takes alot longer than what I anticipated. I would still like to know if there is a better solution rather than wait though.
Firebase Authentication works with a combination of long-lived refresh tokens and short-lived ID tokens. The latter tokens are valid for one hour from the moment they are minted, and cannot be made invalid after they are minted.
So it may take up to an hour before your client gets a new token, and detects that its account has been disabled. You can force the client to update its ID token at any time by calling getIDToken(true). This will ensure the client has an updated ID token, but it won't invalidate the older ID token (since it's impossible to invalidate a bearer token).
What you'll want to do is write the UID or ID token to your database when you disable the user account, and then check for that in your security rules.
Also see the Firebase documentation on detecting token revocation.

Local Notifications vs FCM: Which is right?

I have a fairly straight forward Flutter app which incorporates some "social" features, such as the ability for users to add other users as friends.
When a friend request is "send", a record is added to the Firebase to represent the (pending) friendship. I would like the user "receiving" the friend request to get a notification.
I've looked up a dozen or more posts on using local notifications and FCM, but all I can find are bare-bones PoC style examples. I'm at a loss to understand which methodology is correct for this situation.
Can FCM somehow listen for changes on the database, so when the friend request record is created, it would then push a notification? Or should the receiving user's app be listening for changes to the friend requests and push a local notification?
I'm at a loss for where to start.
Thanks in advance!
The answer is "You have to make your backend listen for changes on the database and send FCM".
If you are using firestore as your database, you can use cloud functions to listen to the changes made to your database. You can read more about it here:
https://firebase.google.com/docs/firestore/extend-with-functions
If you are using a backend of your own, you can make the backend send FCM to a user using the firebase admin sdk for whatever language you are using.

firebase firestore audit log in functions

I have a couple of http functions in my firebase project, because I prefer to hydrate, validate and update the data on the backend. I would like to use the automatic stackdriver logs, but I need to associate the log events with the authenticated user (the requests are authenticated). Is there any way to add some context to database updates? Or commit the changes in the name of the user (not the service account)?
Firestore triggers don't currently associate any information about the end user (not even if you're using Firebase Authentication and security rules), so you will have to write user information into each document in order to track who performed an action on it. It will not just appear in the environment or context.
If you go this route, I strongly suggest adding security rules that require the user to provide their Firebase Auth UID correctly in a document field, so you can be 100% sure it's correct.
Read this for more details: https://medium.com/firebase-developers/patterns-for-security-with-firebase-per-user-permissions-for-cloud-firestore-be67ee8edc4a

Dialogflow and Push notification

I'm actually implementing the push notification (https://developers.google.com/actions/assistant/updates/notifications) and I'm not sure to understand everything.
I'm using dialogflow through webhook json with php webservices, and meant to be used with google home (and phone).
All my tests are done through simulator.
I've created an intent get_store
I've created 2 implicits intents (notification_store and notification_text) and activated them as notification in the action console.
When I go into get_store, i'm asking a permission to send notification for notification_store (to send a gmap link), when the user respond yes, it returns me an UPDATES_USER_ID and set the user permission as true in all next requests.
Then, I use this UPDATES_USER_ID and the get_store to send the notification (it responds with a 200 ok)
Questions :
- Once I've accepted the permission, it will not ask me any new permission, even if I want to send notification for notification_text, which means it's one update permission for all notifications intents?
- I can't delete UpdatePermission from my user, even after using reset button or change version
- I have a doubt, does it work only with a released version (alpha/beta/prod) or even with a draft?
If someone can help me to understand what's possible so I could be able to know what is working, not working, not possible.
Thanks.
When you ask for permission to send push notifications, the UPDATE permission gets cached so you don't have to repeatedly ask the user for permission. However this permission is unique to the intent specified when asking for permission.
When asking for a user's permission to send push notifications, you must specify the implicit intent you are asking permission for. So in get_store, I imagine this intent is set to notification_store.
The following code uses the Node.js client library, but the concept is the same:
app.intent('get_store', (conv) => {
conv.ask(new UpdatePermission({intent: 'notification_store'}));
});
Because of this, you can't use get_store to ask for permission for notification_text. Instead you will need to create a separate intent such as get_text, which specifically asks for permission to send push notifications for notification_text.

Firebase Cloud Messaging for Web - How to maintain the token list in the database and ensure they are valid or up-to-date

With Firebase Cloud Messaging for Web,
How do I maintain the list of valid tokens in my database? For example I've noticed when a user turns off notifications and revisits the site, a new token will be generated and the old token in my database is useless.
I've also tried using Firebase messaging.onTokenRefresh() callback, but it does not get called when I turned off notifications. Also in this case, even if it did get triggered, it returns a new token that was refreshed. How do I keep track of the old token that was refreshed?
Can someone please share with me their thoughts/ways to maintain and ensure the token list in the database are valid or up-to-date?
Any feedback is much appreciated.
Thank you,
Christina
messaging.onTokenRefresh() is probably a wrapper around the event onpushsubscriptionchange.
Indeed that event is currently only called when the subscription is enabled (or enabled again), but not when the permission for push notifications is revoked. So at the moment you can only know that an endpoint has expired when you try to send a notification to it.
More details:
http://blog.pushpad.xyz/2016/05/the-push-api-and-its-wild-unsubscription-mechanism/
In any case you can use the callback to send any new token to the server: at first you will have two tokens stored for the same browser, one expired and the other valid.
Some problems arise if you have data associated to the endpoint (e.g. tag) that you want to preserve during the endpoint change: see the blog post for some suggestions.

Resources