Live user count in chat Swift - swift

I'm attempting to make a group chat app and I want to implement the feature where it detects the number of active users in a chat room. I was thinking of updating the database with the structure below, in the viewWillAppear and viewWillDisappear functions. For example, in viewWillAppear, I would update the current user value into the chatroom node, and in viewWillDisappear, I would delete the user value; however, I was wondering if this is the most efficient way to go about this since it would require a lot of database fetching.
active_chatroom_users
- chatroomId
- UserId:1
- UserId:1

Firstly, you may not want to use viewWill... because it doesn't always mean the following viewDid... will occur. Instead use viewDidAppear and viewDidDisappear. There isn't a problem with creating and deleting the user in the chat room every time the view appears and disappears, however, you're right in thinking that there's one in fetching the chat room users for the count.
You should maintain a count yourself by incrementing and decrementing each time a user is added or removed from the active_chatroom_users. This can be done on the client in several ways, one of which involves transactions. It will allow you to update the active user count in realtime and will ensure that any other users becoming active at the same time will also be counted.
However, I would prefer using a Cloud Function trigger that recognizes when a user becomes active or inactive in a chat room, and increments or decrements the total active user count for a chat room.

Related

How to Implement "Your contact just joined app" feature

I am building a mobile app (in flutter firebase, but the answer does not have to be firebase specific). And I would like to implement a feature that notifies users whenever anyone from their contact list joins the app. This seems like a very EXPENSIVE feature.
At the top of my head, I see a lambda/cloud function that is triggered everytime a user joins and then searches a database of users and their respective contacts for the existence of the new user's phone number. To me, this solution does not scale well for two reasons: if the number of total users is in the millions and the number of users joining simultaneously is a lot.
My better solution is to get the user's contacts upon joining and then searching a database of current users contacts for any of the phone numbers of the newly joined user.
Is there a solution better than the second one? If so, what is it? If the second solution is standard, what kind of backend storage mechanism provides the best search and retrieval time for a database of users and their respective contacts?
In the case of large users ill not do first solution because that may slow the sign up process instead i will creat a cron job that runs at a specific time or periodically it will get the list of the latest users signed up that day or that hour whatever you prefer then that cron will check the new user if related to any user in the databases and send a notification right away, or a better solution create a temporary table in a database in another server insert the notification informations into the other server, creat another cron job in the second server it will run at a specific time to sendthe notification

Ban a User in a particular firebase firestore group chat for predefined time

I am very new to coding. but i managed to build a group chat app using a low code platform called flutterflow. i managed to spend significant amount of time on it and was able to build a public group chat app except few functionalities. I am hoping to find help from here. for the following questions.
I have chat mods appointed on a group level. like if you create a group, you are a founder and you can assign mods to that perticular group chat. now i want these mods to be able to ban a user in that particular group chat.
I have tried created a subcollection in groups called "banned user" and created two feilds. one is "banned users" document reference to users. and another is "banned_till" to record a time stamp until the user gets banned.
Problem with this is when i ban a user twice, it creates two documents in the user reference with the same user. and two documents has different "banned_till" times. which one it is supposed to pick?
i tried to do this and put a conditional visibility to the chat that "if current time is less than or equal to banned_till time" it wont let user type in the textfield to chat. but this is giving me gray screen.
I am very new to this. any help would be appreciated.
there is specific way to do so. you have to set custom logic. like save all banned users in a firebase database object with thier max time and procced next.

How to know the count of repeated entries in Firestore flutter?

I'm creating a appointment app in flutter using firebase in which I have keep the track of people that got appointment repeatedly based on their phone number . How do I get this count of repeated entries?
it would be better if you add some code and more information to your question so we can can answer correctly but based on my understanding you want to check if this user repeatedly booked appointments using your app considering that it is a logged in user not a guest,
in this case inside your Firestore collection that contains the users i assume that each document represent a user add to each document (user information) a counter (integer variable) called for example "appointementsNumber" and every time a user book an appointment this counter will be increased by one, in this case you are able to know how many times this user booked an appointment.
hopefully i did understand your question correctly.

FIrestore chat rooms with bucketing

First i'd like to add that while this is a Firestore question, im open to hear suggestions about integrating an additional Google service.
The System
I have a chat feature in my application. Since there could be a very decent scale, I decided to have a limit to a chat group.
Chat groups are not created by users and should be created automatically by using some sort of an incrementing index (e.g: room_1, room_2, ...., room_n).
The limit on each chat group is 100 users at most.
So if I have 100k users online, I'd expect to have 1k groups (aka n=1000).
The Issues
How can I distribute users, upon signing in, to chat groups? (Lets say the strategy is to fill current rooms first, hence the 'bucketing' in the title)
Since users can close the app without pressing "quit" or something, I need the system to know to adjust
You can add a counter to the room document and increment/decrement it using by FieldValue.increment, here is an usage example in Javascript:
//when a user enter the room
db.collection('chat_rooms').doc('room_1').update({
userCount: firebase.firestore.FieldValue.increment(1)
});
//when a user quits the room
db.collection('chat_rooms').doc('room_1').update({
userCount: firebase.firestore.FieldValue.increment(-1)
});
Since FieldValue.increment() gets the current value of the counter you don't need to worry about racing conditions, which is good given that you expect to have a huge number of user so this will be constantly updated.
You can wrap this arround a check of the room counter and if the room is over the limit of users you set for rooms a new room can start being filled.
For your second question a bit more information is required, but assuming you are using android you can use the onAppBackgrounded function in the example provided in this community answer to call the update that decrements the counter in the chat room document if the app is backgrounded or closed by the user, as part of the "forcing" him out of the room.

Firebase cloud functions chess game Swift

I am making a chess app which has a Firebase backend, i am using cloud firestore and cloud functions. basically i am using node 8 to avoid billing issues on cloud functions, i can call and trigger, but i can't wrap my head about how to make an action happen on another device instead of on my own.
After authenticating and logging in, the user gets into a lobby which is a tableViewController and there are shown only the users that are currently logged in.
What i want to achieve is by tapping on a certain row the user that got the tap on it gets an alert shown for him which states whether he accepts the challenge or he declines it. Based on that i proceed to the game or do something else.
The question is though how to make this alert trigger on the other user's device?
Also i've seen some posts that it can be done with snapshotListener on a document, but again i run into the problem of understanding how to trigger the alert on another device. If you've got some other good ideas please share!
Thank you for any feedback!
I think snapshot listeners are really the only way to go. You could use other Firebase services but those aren’t the right tools for the job. Consider creating a collection, maybe call it requests:
[requests]
<userId-userId> (recipientUserId-initiatorUserId)
initiator: string
recipient: string
date: date
Each user has a snapshot listener that listens to this collection where their own userId is equal to recipient. You can add a date field to sort the list by most recent, for example. When a user wants to challenge another user, all they need to do is create a document in this collection:
<userId-userId> (recipientUserId-initiatorUserId)
initiator: myUserId
recipient: theirUserId
date: now
And the recipient's client will instantly see this document.
You could include dressing data in this document, like the initiator's display name or a path to their avatar. But this data may be stale by the time it's rendered so the alternative is to fetch the dressing data from the database using the userId. You could also auto-gen the document ID but if you configure it (like this), it can make operations like deleting simpler. You could also configure the userIds to be alphanumerical so only one request can exist between two users; but if they requested each other at the same time, one would overwrite the other and you'd have to handle that potential edge case. There are lots of things to consider but this is the starting point.