How to handle FCM subscribeToTopic and unsubscribeFromTopic with Flutter - firebase

I am developing an app for which I use firebase as the backend. I am using FCM to send notifications to my users, however, I am not yet grasping how to use subscribeToTopic and unsubscribeFromTopic.
My use case (which I do not know how to get it working):
After a user installs the app, he will be subscribed to the main topic of the app (I have this working). The user could then go to settings to unsubscribe from the main topic (I do not have this working).
The struggle:
All the different tutorials I find describe how to subscribe to a topic, they call subscribeToTopic('some topic') in initstate of the welcome screen. Is it required to do this everytime the app starts? What happens when the user calls unsubscribeFromTopic('some topic') and the next time they start the app subscribeToTopic('some topic') is called again in initstate?
My idea: first time the app is loaded I call subscribeToTopic('some topic') and never again. Then in the settings screen a user can unsubscribe (and subscribe). Does this work? What should I pay attention to?
Thanks in advance for helping!

You check if the app is launched for the first time by either using shared_preferences which stores this information locally or by storing a variable on Firestore that tells you if the user has logged in to the app before.
You subscribe to the topic if it's the first time and if it's not, you do not subscribe.

The first time you open the app show a welcome screen or something like that, where you ask the user to receive notifications or not (which is always more user friendly).
If the user continues you save this value in a local database like shared preferences or hive.
If the user subscribed you call the subscribe to topic method
If the user does not subscribe ofcourse you do nothing.
Then on the settingspage:
Show a switch which value is gathered from the local database you already defined.
When the user taps the value is stored, based on this value you subscribe or onsubscribe.
This is how I have done it in my app where I also use topics instead of tokens.

Related

Customize push notification with a text, the user can choose

i want to create a push-notification out of xamarin.forms, where the user can choose the text.
Like, the user want to get a reminder for something called "Dad's Birthday".
I have seen i can create push-notifications with firebase, where i can write down something, but i want the user to customize text to shown in the notification.
e.g.
User opens the app, create a new reminder called "Don't forget to drink enough!", set the timer for tommorow 4pm save it and close the app. I don't want to get a notification, only shows something standard for all like 'You have a reminder.'
Maybe there are other services except firebase they can do it?
Is there any way for it?
For your requirement you dont have to actually use the firebase firebase messaging instead. Use local push notification , in your case that best suits your requirement. Use firebase i.e remote push notificatoin only when you want some non user of the app to send the notification to the user of the app , it may be via another app or firebase console.
Answer from - Krishna Acharya

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.

Listening for changes in Firestore database in and out of the App - Swift

I need to listen for update on the client side whenever something in the Firestore database changes.
I need some clarification about this topic:
Let's say that we want to notify the user whenever a new document is created in a collection:
We have 2 cases:
when the user is on the app
when the user is out of the app
for the second point I can create a cloud function firestore trigger that notifies the user through the push notification service
But on the first point I don't know which is the best approach.
(maybe setting up a snapshotListener? but how can I do that on the global scope of the app? Is it the right approach?)
Should you implement a FCM notification for the second scenario, the notification will be fired to your app no matter if it is on background or foreground, so you can use this approach for both situations actually.
You can use this solution to not fire a notification (on the frontend) and in case you don't want to fire that if the app is in foreground you can just keep the completionHandler() blank and that's it.

Swift - FireStore/FCM (Firebase Cloud Messaging)

I've incorporated Firebase Cloud Messaging into my app. After messing around, I kind of understood the premise of how it operates. So, as a result, I structured my code so that when users sign up the FCM token is stored. After creating two accounts, I realise both FCM tokens for the user were the same.
Looked online and sorted this issue, and now I can refresh the token on launch, and still append the new FCM token when users initially sign up.
So now, I ask the question - Users are created with a fcmToken field (which I can refer to in my code), however, due to the fact a new token is generated on launch each time does this render the token(s) stored for each user useless? Or can I still push to the specific user using the fcmToken?
I've looked online, but can't seem to find an answer.
FCM tokens don't uniquely identify an individual end user. They identify a specific installation of an app on a specific device. When sending with that token, it doesn't matter who is signed in to the app (or if anyone is signed in at all) - the app will still receive it and need to figure out what to do with it. It's up to you to decide what to do with that message, given the sign-in state of the user. If you expect that your app could have multiple users sharing a single app on a single device, then you will probably want to send something in the payload to determine who that message was intended for, if necessary.
#doug great answer, but there's a common implementation problem when people share a device, so please add a warning, something like: often only the last logged in user should receive push notifications, otherwise he could see messages from the person who was logged in before. your backend should not only store all the devices a user is logged in, but also for each device who the last active user is and check this upon sending a push. the question whether you receive push or not when logged out is a common topic, too.

Dynamic Push Notifications

I know that Firebase has recently added support for Push Notifications and while this is a great thing, I only seem to be able to send push notifications manually via the Notifications Panel.
What I'd like to do is to send push notifications within a user scope...Let me explain that. Each User in my App has an account and then each user can join a group. Within this group the user can perform tasks and has a list of chores to do. Now when certain tasks are due for example I want to remind the user of doing it with a push notification. For 1-10 I might be able to pull this off manually, but is there a way to dynamically based on the data in the Database send out Push Notifications?
I know that certain Push Notifications can be created using the Analytics tool such as "Hey you have not visited for 3 days, please come back whatever"... but I'd like to register push notifications such as "I just created a task, this task needs to be done within 3 days. Remind me in 3 days if the task is still not done".
Is this possible with Firebase or do I need to have my own server connecting to Firebase and handling those events?
-xCoder
You need to implement FCM in your client and in a server. Let me put this straight:
First, you need that your client, or app, to register into FCM and get a FCM token that will be used to identify that device uniquely.
Then, store that token wherever you like. It can be into firebase database or other server you may like. I recommend you to store it into firebase if you are using it as a database for your users; that's my case.
Also, you need to implement a http or xmpp server in order to send FCM messages to your registered devices containing the data you are interested in. For example, you can implement a Google App Engine endpoint (can be done with Android Studio and Java) that is quite simple or a NodeJS module, depending on your preferred language.
If you are using Firebase as database you can connect from your server with the appropriate SDK and get the FCM tokens you want from your users, and then send the message to those with data. Don't forget to secure your serve.
The way you implement your server algorithm to send FCM messages depends on your app purposes.
Hope it is clear enough for you. Also you can find all the documentation with a short video that explains the general structure here: https://firebase.google.com/docs/cloud-messaging
You can use cloud functions to trigger on any create, update or delete operation in your database and in the trigger event, you can choose to send in FCM push notifications to the devices of your choice.
Here is the documentation regarding the use and structure of a cloud function: https://firebase.google.com/docs/firestore/extend-with-functions
Hope this helps!

Resources