how to send notification to user on data change in realtime database - flutter

the problem is if there is any change in notification/154578/0 or in notification/154580/0 (and more child with different id) I need a firebase cloud function (index.js) that will be triggered on data change and fetch the id from notification ether data changed in 154578 id or in 154580, get that particular id and move to eg: fcm-token/154578/value : sldal9854dfas (<- it also in realtime database shibling of notification) get this value and send notification to this token.
Actually I'm a beginner I don't know how to do this if anyone can help me, it would be great help for me
thank you.

Related

Firebase functions solution for building a secure Chat App with Seen functionality

I am building a chat app using Flutter and Firebase.
The way it works in Firebase Firestore is really simple, I just have a conversationId which represents the documents where there are the messages, all of the users have a list of their conversations, when they tap on a conversation, a new screen pops up where they see the messages based on data from the stream of the "Messages" collection that is under the conversationId document. Basically that's the structure
col: Chats
doc: conversationId
col: Messages
message documents...
And this is how I get the messages inside the Chat Screen.
_firestore
.collection("Chats")
.doc(_messageCollectionId)
.collection("Messages")
.orderBy("sentOn", descending: true)
.snapshots()
.map(...)
The message document is basically the message text and when it was sent and who sent it.
I want to create the "seen" functionality, inherently I want the user to see what conversation he read or not (which ones have new messages, like instagram chat or discord)
I can not come up with a good solution to this, my main 2 problems are:
If I were to call a cloud function which fetches the messages and somehow marks them as being read, that would break my app, as I need a continous stream of live message data for the chat to feel good, I can not stream data from the cloud function.
I would like to create a system which is not write intensive. If I would have to mark each message document in particular with some "seenOn :timestamp" value, that would mean that if the user is reading 200 new messages, there are 200 new writes on each document, which seems too much to me, there should be another way.
I am asking for guidance on how I should go about the architecture of such a chat using Firebase. Maybe my chat model is not really fit for what I need, how should I tweak it?
Another problem is that I do not know how the "seen" signal should be sent. If I manually write to a document and change the boolean value of some "isRead" field from my client, the client could easily skip that line of code and break my whole seen system, they could read messages without sending the seen signal just with a break point. This is quite exploitable, there is no cloud function trigger on documents "onRead" that could help me move that logic outside the client, so what is the solution to make this also secure?
so if you want to create the seen function you could made the database structure look like this first
you should create 2 collection for the db, the users collection would only save user data and in the chats collection inside of the uid is saving the chat room id that would be look like this
that was the collection inside of users. only put the roomId of connection that been made when user trying to send a new message to other user. put the the field exactly look like that. after that you could create a chatroom collection that look like this
to be sure that random uid inside of chats collection is a room id that you should register in your users/doc/chats/ collection. the field inside of the roomId would be a connection between of the 2 user for accesing the message that've been send to db. and inside of the chat collection you would send message data in this format
and after you put that you could retrieve the chat data using stream function that would look like this
Stream<QuerySnapshot<Map<String, dynamic>>> streamChats(String chatId) {
CollectionReference chats = firestore.collection("chats");
return chats.doc(chatId).collection("chat").orderBy("time").snapshots();
}
each time of user sending message you could put the total of message that've been send to other user in the total_unread field and update it when other of user open the chat roomId. and tada your seen could work properly
oh and you can create a function that check the total_unread is 0 already and you can put the seen/check icon beside of your user message bubble.

How to setup user notifications with multiple recipients and read status in MongoDB (Meteor app)

In my Meteor app I have a mongo collection Notifications for user notifications, and I want to keep one document for one notification, even in case of multiple recipients. In each notification I have an array with users IDs. And I need to keep tack of read status for each user.
I tried to use an additional array to record who've read the notification like this:
{
...notification,
users: [id1,id2,id3],
read: [id2]
}
But two arrays cannot be indexed properly as I understand the docs. So my current approach is to have separate collection of UnreadNotifications with the documents referencing actual notifications by IDs and linking them to the users like this:
{
notificationID: notificationid1,
userID: id2
}
When the new notification created also a number of unread notification documents created for all the related users. When user reads a notification, the document is removed from mongo. Does this approach make sense? What are possible downsides?
The one issue I can think about is that user will probably have to fetch all of his unread notifications at once to be able to display witch of the real notifications are read. But it doesn't sound that bad.
Ok, think from a client perspective. I need to get my notifications in the lightest way possible. I don't want other people's notifications, I don't want to construct my data via aggregations.
Your Insert/create notification Meteor Method can have 2 function:
Insert the actual notification. If you have 10 people, 100 people, that is 10 ... 100 notifications.
On the user, write the increment of a notification count and eventually have it published with the other user details so that you can have it displayed.
When you open your notifications, you have a couple of options:
Read them all (write to db a "seen" or "read" field = Date.new() for these notifications. This field will help you style the notification as well seen - not seen.
Read on click of notification if in your UX a notification has to be opened. For example, I think in FB you have to click a notification to read it while in LinkedIn, opening notifications reads them all at once.
Use a library for in-view and only read those notifications that are in view, as you scroll in the list of notifications.
1 is the easiest to do and you also reset the counter on User to 0.
In summary, your insert notification method would be something like:
'methodName': async ({ notificationObject, userIds }) => {
...
userIds.forEach(id => {
- insert your notification
- increment user counter
- send a push notification
- or send an email
})
}
If you do this server-side and need to insert notifications from multiple methods such as: someone liked your something, someone sent a message to you etc... these are multiple methods that will be calling your insert notification method. In this case, if everything happens server side, better have the notification insert as a function instead of a method.

How to atomically delete user and user's data from Firebase Auth and Realtime Database respectively?

Some background
When a user account is created, I do 3 things using callback chaining in the sequence 1 > 2 > 3.
A user is created in Firebase Auth (the standard way using createUser(withEmail ...))
I upload the user's profile picture to Firebase Storage and capture the returned downloadUrl for use in step 3
I store the user's other information (including the downloadUrl from step 2) in a node in the realtime database (keyed by $userid)
Now the problem
I provide a button called 'Delete account' which should enable the user to delete everything. That is, clear all their data in the Realtime Database, clear their profile picture in Firebase Storage, and finally delete their account from Auth. The important thing is that all these operations should succeed or be canceled if even one fails.
I've gone through ~10 pages of S/O questions & answers, there was 1 unanswered question like this one (it asked about the account creation process...I suppose an answer to that question can easily be adapted here.)
What have i tried?
Currently, I use callback chaining like so:
// start by atomically deleting all the user data from the Realtime Database using the fanout system.
- get all appropriate locations and save in fanout dictionary
- update all these locations to nil // atomic goodness :)
-callback:
-on failure:
- just return // no worries, nothing has changed yet :/
-on success:
// proceed to delete user files on firebase storage
- delete path $userid on firebase storage
-callback:
-on failure: // this is bad, no idea what to do :(
-on success:
// proceed to delete account from Auth
- delete user account from Auth
-callback:
-on failure: // this is terrible, also, it could happen often b/c firebase does ask for re-authentication sometimes :(
-on success: // thank goodness! I have an authListener somewhere ready to show the 'signInViewController' :)
How do you handle such multi-system (Auth, Storage, RealtimeDB) operation atomically? I have looked into transactions but can't see how they can be adapted for this - the docs only show them being used in incrementing counters for likes/stars etc in the RealtimeDB.
Any help will be very much appreciated.
So the main problem is what to do if the data you're trying to delete is being deleted only partially.
I think you should think about a method that will help you restore it if something goes wrong.
I'm not on my computer now but I suggest you to try to download the data that you want to delete and only if there were a success you delete the local copy too, otherwise you should be able to restore it easily.
Edit: if we talk about a serious amount of storage instead of a local copy you can make it on the cloud.
So you first copy this data, then delete it, then delete the database data (also copied previously) then you can delete the user account and finally you can delete the copy.

Swift and Parse for messaging app?

I'm relativily new to databases and Parse, but I'm trying to set up an app that can recieve and send messages between users. I've managed to set up the sign up and log in process, now I need to get the devices communicating.
Do anynone have any idea how to make this happen? I can imagine you'll have to create PFObjects with ID's and classes with some user-details so that only the two users communicating can send and retrieve messages to each other.
Any suggestions on how to set this up would be very appreciated.
Sure enough there are huge ways to setup communication between devices. But it totally depends on your communication needs.
For example, if you need "real time" communication,
like peer-2-peer, then you need to start looking for external service, such as PubNub, because you can't do that with Parse.
If you are trying to build some chat like app, then you can go with manually refreshing and
push notifications.
So, to do what you want you need to create message object and setup ACL for it
PFObject *groupMessage = [PFObject objectWithClassName:#"Message"];
PFACL *groupACL = [PFACL ACL];
// userList is an NSArray with the users we are sending this message to.
for (PFUser *user in userList) {
[groupACL setReadAccess:YES forUser:user];
[groupACL setWriteAccess:YES forUser:user];
}
groupMessage.ACL = groupACL;
[groupMessage saveInBackground];
So, here we've added ACL(access control list) rule for our message, to allow all users from userList access that message.
Also, don't forget to include additional information for message like 'recipient', 'sender' etc to be able to create queries using it. For example, to retrieve all messages send from concrete user.

Alfresco Data Lists and E-Mail notification

I have created a custom Data List and now I would like to send a notification every time that a record is created or updated. The thing is that I would like to include the information inside the record in the e-mail body and I have no idea how. I tried with rules but I can not add the information of the record to the e-mail. Some ideas about it?
Thanks in advance!
You can create policy which will fired when you user is creating node of particular type of datalist.
Take below example
Node inside data list is of type "dl:customNode" Than create policy which implements OnCreateNodePolicy(This will be only called when user is creating node of type "dl:customNode")
Inside Write your code to send mail notification.You can inject your required services in same.