Send notifications to user in android studio - android

I want to build a notification system in my Android app where I can send a notification to someone upon an event. For example, my app is about a social system where it uses Firestore database (Firebase) to save its users (which means I have a 'users' collection in there), and I have an 'Add as Friend' feature.
Everything works just fine, but I would like to add a feature where when user1 adds user2 as a friend, I would like to send user2 a notification about that.
I have searched in google and saw this post: https://www.geeksforgeeks.org/how-to-push-notification-in-android-using-firebase-cloud-messaging/
Now, from what I understand, this wouldn't help me much cause it only sends the notification from FCM by me (and not to a specific user).
The problem is, I don't really know what to search for (or what to type in google) in order to find what I'm looking for.
Some ideas I thought:
to make a collection in firestore called 'Notifications' where it holds usernames as documentIDs
when user1 sends a friend request to user2, I would add data (like title/message) to 'Notifications/user2/'
But I'm kind of stuck here, I would like to know ideas or if you guys have threads on how do I implement this, I really don't know what should I look for.
Thank you very much and sorry for the long post.

Firebase creates a userID for every user and a usertoken which is a temporary identifier for the device which is connected to this userID. You need to save the usertoken when there is a new one being created in a database(firestore) along with the user with whom you identify this person.
When someone adds this person as a friend you can add a notification in the database that there is a request from person1 to person2.
This change in the database can trigger a cloud function that reacts to changes in the database.
The triggered cloud function sends an FCM to the person which is being added as a friend. This FCM can either be a pure notification or you send data and let your app handle how this data is being handled(saved in a local database or displayed as a custom notification).
Keywords are: FCM, Notification, Firestore, cloud functions, and firebase token
Edit (Answer to 1. comment): Firebase userID and usertoken are created on the device. In the tutorial you implement FCM(I didn't read it complete) and a class called FirebaseMessagingService, from which you can inherit. This class is called, when a message is sent to the device and contains a method called onNewToken. This message is called, when the Firebase Server creates a token for your device and sends it to the device. In this method you might want to send the new token to your database and save it as an identifier for the user of this device. The Tokens are used by firebase to identify devices, to which messages are being sent(You can read about FCM in detail)
Cloud functions are something you can deploy along your firebase project, which get triggered when an event occurs. For example a http call, or a specific change in your database. Cloud functions are written in JS and need to be deployed for your firebase project. (Cloud functions are not for free and you need to pay for each call, but you have some thousand uses for free each month.)
You send a FCM to a specific person by creating a firebase message which is directed to a specific token, tokens or user groups. To identify the person to which you want to send a message you need to have the token for this user, that is why you are saving the tokens from the 1. part in your database and always update the token, when the token changes on the device.
Keep in mind, that a user might use multiple devices. You should have an identifier for you, such as username and along this username you save multiple firebaseIds and Firebase tokens. A single FCM can be directed to up to 100 tokens.

Related

Firebase push notifications for users with specific firestore fields

I'm currently making a chatroom-like app that works with firestore to connect users to a host's session. I ran into a problem where client devices lose connection / stop listening for firestore changes when locked/backgrounded for too long (to my knowledge it's because the device tries to save power by killing long-living processes). I learned that a workaround would be to send a FCM push notification to devices prior to changing the firestore doc so it'd reawaken the app and have the app listen for the firestore doc change. I'm not sure how to implement push notifications, but I learned that it requires a user specific token (that must be protected). Ignoring the fact that I'm not sure how to implement push notifications (noob-friendly pointers would be appreciated), would uploading the user token to firestore as a field be a viable approach? I'm thinking that I can use my helper function (which gets all non-hosts of a specific session) to also send push notifications to each person.
_vibrateAllDevices() async {
var lobbies = await lobby
.where('lobbyCode', isEqualTo: _lobbyCode)
.where('userRole', isEqualTo: 2)
.get();
lobbies.docs.forEach(
(document) async {
document.reference.update(<String, dynamic>{'vibrate': true});
},
);
}
Each lobby is expected to have anywhere from 2-30 people so looping per person doesn't seem to be that big of an issue. Does this seem like a viable approach or is storing tokens to firestore an unsafe? I should also mention that each lobby is expected to only be opened for a short amount of time (~3 hours max) and all information is deleted right after.
Firebase through notification if another subscribe to your own topic make sure that another person subscribes the topic when Firestore field is created. When you trigger notification then automatically receive notification in another person in FirebaseMessages service class in which method onmessagereceive.
There is the same way to trigger a notification in firebase and Firestore because server key always same.
I recommended you to read this documentation:
https://medium.com/mindorks/send-device-to-device-push-notification-using-firebase-cloud-messaging-without-using-external-769476c79ffd

Firebase Cloud Function : Send notification to all user using sendToDevice()

I am already using Cloud Messaging feature in Firebase and utilized the sendToTopic() legacy method of sending notification to all subscribers but I've seen a limitation using topic in my app. Now I want to manage my way of sending and receiving notification by sending notification to each device using the registered device token in user's document which stored as map object. I will iterate to each device token and use sendToDevice() to send notification to each device.
I have now a function lets call it new_added that triggers whenever new document is added in a collection. Now every time new_added function gets called, this will iterate to each document in Users collection and write a new document under Notification collection. The structure would be this Users (collection) > uid (document) > Notifications > doc. Every new added item under Notification collection will trigger a function in server. This operation is too heavy specially if there is a million number of users, does this kind of operation can be perform in server side using Cloud Function within 540 seconds which is said to be the maximum runtime of a function after gets trigger? I really want it to work this way. Is there any tool that will help to minimize the operation?
If sounds like you're trying to implement your own FCM messaging fan-out, sending the same message to many users. This is similar to what FCM topic messaging already does, to I'd definitely consider using that for the moment.
But if you want to implement it yourself, consider how to optimize it for the underlying system. Since you're storing the tokens in Firestore, the number of documents you read is a key factor in the cost.
A way to reduce the number of documents you read could be to store the tokens for a group of devices into a single document. For example, you could create a document for each "topic", and add tokens to that doc as they are written to the database. Then when you need to send a message to all devices for a topic, you simply read that topic-document, and get all tokens in one go. This becomes especially simple if you name the document after the topic for which it contains the tokens, e.g. mytopic-tokens.
The main problem with this approach is that a document can be no bigger than 1Mb. Say that tokens are at most 256 bytes (they seem to be 152-162 characters), you can store 4000 tokens in a document. If you have more tokens, you will need to create multiple documents. A simple naming scheme can go a long way here, such as mytopic-tokens-1, mytopic-tokens-2, etc. You can get all these documents with a single range-query in Firestore.

Using FCM token for signIn instead of user email

I don't want to have login or signup for my app. I've implemented fire-base notification in the app as well.
Can I use Fire-base FCM ID (token) as a unique user identifier. Instead of creating a user in the system I'll create a FCM table(id(pk), FCMID) and store all information of the user against that FCM id.
If yes then at what instance it changes the FCM id.
You can but you shouldn't
FCM token can change if you see the Service used for getting the FCM token, the one that has to extend FirebaseInsanceIdService the method inside is called onTokenRefresh() because it will be triggered every time the FCM token is refreshed for a new one. In previous Google Cloud Messaging (GCM) this strike to me as erratic, but in current FCM it seems to be infrequent.
You could do this by saving the current token in some form of local persistence (sharedpreference, database, etc). Then when the FCM is refreshed using the stored FCM the nodes in the real-time database can be updated.
This will have some bad scenarios: what happens if the user re-login by reinstalling or changing device? The first can be solved by saving something unique in the device, I have seen that some sort of devices ids can be get, but those are reset after boot or factory reset. Then a more general solution would make the user to input something unique to them every time they log in. It could be the email, or it could be the phone number.
Which leads me to, use phone authentication instead
i hope tis is helpful to
this is mydb in fcm
db structure in json like,
walinnstracker{
active_users{
info{
"count" : "13",
"female_count" : "0"
"male_count" : "0"
}
}
}

How to receive a notification to android user, when ever firebase database is updated?

I have an android application connected with firebase. When ever a new child is added to the database I need the user to be notified via a notification message. Moreover, in my application the user selects a code (eg: 71000,00100,90288) and this code is stored in shared preferences. I need the user to be notified when ever a child is added or modified, only as the code selected by the user. Any help, highly appreciated.Thank you so much in advance.
if your server side is firebase ,to send notification when child added , you need to create a firebase cloud function which will do that
so this what you will do :
create firebase cloud function
send data with notification ( using payload )
after receiving data in your service ( Messaging listner )check if the data ( number ) is equal to some of saved numbers in shared preferences
On firebase, we got callbacks to provide realtime database functionalities.
Ways of doing so:
Register a onChildAdded listener to the firebase node URL and it get triggered whenever a child is added and you can run a service that could cause notification payload which run on client side.
use Firebase cloud functions which run on service side.
Once i developed such application, in order to achieve this i used broadcastreceiver which was monitoring my data base for new information. (It is just suggestion)
But u can still make use of this tutorial

Synchronize Android client and REST server

REST Server
I created a Rails server that contains :users and associated :comments. It is used as a backend API for an Android client. The exchange format to load and store data at the server is JSON. Here are the relevant migrations.
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :name
t.timestamps
end
end
end
...
class CreateComments < ActiveRecord::Migration
def change
create_table :comments do |t|
t.references :users
t.string :subject
t.text :message
t.timestamps
end
end
end
All users have already been imported. Therefore, only read access is configured for the :users resource. Thus, for :comments it should be possible to add new entries. Here are the available routes.
user_comments GET /users/:user_id/comments(.:format) comments#index
POST /users/:user_id/comments(.:format) comments#create
new_user_comment GET /users/:user_id/comments/new(.:format) comments#new
user_comment GET /users/:user_id/comments/:id(.:format) comments#show
users GET /users(.:format) users#index
user GET /users/:id(.:format) users#show
Android client
On the client side I use a Service with AsyncTasks to download, parse and store users into a local SQLite database. A ContentProvider delivers cached users to the UI. The user object downloaded from the server contains the unique id of the users table. This should be useful when a new comment gets created on the client.
Scenario 1: Read comments
Users are displayed in a list view on the Android client.
A user item gets selected.
The list activity creates an Intent which contains the user specific URI, e.g. content://com.example.myapp.provider/users/23.
A user activity displays detail information about the user and associated comments.
Cached comments get loaded via a CursorLoader. (1)
A synchronization process loads comments from the remote server. (2)
Scenario 2: Write comments
A comment can be created from the user activity.
The comment gets stored into the local database. (3)
Stored comments are sychronized with the remote server. (2)
Headache questions
I marked the scenario steps that are associated with the following questions.
How do I create a content URI for the comments being used with a CursorLoader in the user activity? Please mind, I only know the user URI at this point.
Can someone describe how I create a synchronization process? I am not sure if a SyncAdapter works here (never used it). Is the the synchronization process just a Service that on the one hand starts tasks to download, parse and store comments on the client and on the other hand loads, encodes and sends out comments to the server?
How does the content URI for a new comment look like? Is the ContentProvider for comments the same as for users? Is there only one SQLiteOpenHelper in the application?
The main problem I am struggling with is how to design the application? If you know of a better solution on how I should synchronize the users and their associated comments, you are very welcome.
Answers
Answers to question 1. and 3.
I extended the REST model as follows: The JSON hash returned for a comment now includes the id of the associated user. The same id is also included in the JSON hash for the user. Both objects are stored into the local database on the Android device. This allows me request comments for a specific user. I simply pass the server user id as WHERE clause. The content URI for comments is not cascaded as I implied with my question. It is similar to the user content URI:
content://com.example.myapp.provider.commentsprovider/comments
Note, that I changed the authority part of the string. I decided to create separate content provider for users and comments.
One simple architecture is to always update things in the server first, sending posted comments to the server right away and from there pushing a notification through GCM to users that should request the updated comments list. The flow would look like:
When the app is open send GCM registration id to your push notification server (say uniqush-push, or your own server using a gem to handle the GCM logic), this way you can use it to send push notifications to the user telling the app to update the comments from the server
Build your initial cache as you want it
Whenever a user posts a comment, send it to the server and make the server respond with the data for the created comment, so the app can use that and already cache it if it wants, using the returned id and whatever else
On the server, when a comment is posted, loop through all the concerned users and using the GCM registration id send it a push notification, it could be as simple as having just "update_comments": "1"
On the app when the push notification is tapped by the user, update the comments cache with a request to the server

Categories

Resources