Adding notifications to my web app - firebase

I'm creating a chrome extension that allows users to chat with one another. I've finished the basic implementation and want to add notifications that tell a user if they've received a new chat message since the last time they were connected. I have an idea of how I want to implement it but need input on whether it seems feasible and suitable.
Basically, my database is structured so that there is a list of users and chatrooms. Each user has a section called chats which lists all the names of the chatrooms they're in:
What I plan to do is the following: In every chat under each user's chats section, instead of setting its value to true, I set it to the last time they disconnected. Then in each chatroom, I add another field after user2 called timeLastMessageSent and always update it to the current time a new message is sent.
With that information, every time a user connects I'll loop through the chatroom's listed in their chats section and see if the value of timeLastMessageSent is higher than their last disconnect time, which means a message was sent while they were away and I can add some sort of notification that they have a new message.
I'm relatively new to firebase so if anyone with more experience can tell me what they think of my idea I'd really appreciate it. Is this idea feasible? Am I approaching the problem correctly? What sort of commands should I get familiar with to achieve this?

Related

How to know if a message is seen or not

We are displaying list of messages on user message feed. Messages are stored in a feed collection, where its organized by users. We want want track if user has seen the message or not
feed/{user_id}/
{message_id1: {seen:0,score:0.2}}
{message_id2: {seen:0,score:0.2}}
{message_id3: {seen:1,score:0.2}}
At present we are thinking to update "seen" boolean for a given message if user has seen it. Are there more efficient ways to do this in firebase (e.g. firebase native analytics). Not sure if doing so many writes back efficient
There are two common ways to track what messages a user has seen:
Keep a flag for each message that the user has seen.
Keep the timestamp/key of the most recent message that the user has seen.
The letter is a lot easier to implement, but relies in the fact users typically read message in order: scrolling from their oldest unread message to the newest message. If that is not the case for you, there's not really a better option than tracking the status for each message (and in a multi-user chat room, for each user too).
Also see:
How to structure NoSQL messages to get unreads by 1 query? (long explanation with examples of the same use-case, but then for Firebase's Realtime Database)

Reading list with Dialoglfow fulfillment from Real-Time Database

I am creating a chatbot using Dialogflow and Dialogflow's Inline Editor (for Cloud functions and Firebase database "Real-Time Database"). I will integrate this chatbot with Google Assistant.
I have to read a list from the database, wherein the list has several children, few of them have sub-children, and few of sub-children have sub-sub-children. Because the output is a list and consists long-text, it will take too long to speak all data at once. So I would like to output one child from the list and ask the user for permission (Yes/No) as "Do you want to read the next?". If the user says "Yes", I will continue reading likewise until the end. And if the user says "No", I will trigger an event. Asking for the permission from the user is true before reading a child, even sub-child, and even sub-sub-child.
The approach that I have taken involves creating a separate DB record for each user when they first request the list, to keep track of where they are in the list. When the user says yes, get user’s current item id from the database, get the next item in the list (return it to the user via agent.add) and then update the user’s DB record to the next item’s id and so on until the user reaches the end of the list. After agent.add(), ask for the permission from the user by agent.setFollowupEvent(). If the user says no, just reset/delete the DB record for that user.
Few questions I would like to ask:
How will I identify each user as an individual: by some id, session, or something else?
When I run the below code in return cloud function, agent.add is overridden by agent.setFollowupEvent. How do I stop this?
agent.add('I will print the list here!');
agent.setFollowupEvent('SOME_EVENT'); //invoking an intent to ask for the permission.
You have a few issues you're trying to raise here, in addition to the one you're dealing with. Looking at each:
How can I stop setFollowupEvent() from overriding the message I've set?
You don't. The entire point of setFollowupEvent() is to switch to a different Intent instead of the one that is currently being processed.
Most of the time you think you want setFollowupEvent(), you probably don't. Don't use it.
So how can I add the question at the end of what I'm saying?
Just ask it.
Really, it is that easy.
You can either include it in the string you're sending to agent.add(), or (depending on the details), you can do a second add() with the prompt.
But don't I need to trigger an Intent to get the answer?
No. That isn't what an Intent is for.
Intents capture what the user is saying, not what you are asking or what your agent is doing. Your fulfillment does something based on both the Intent that is triggered as well as the rest of the state that you know about the conversation. But the Intent is just one bit of that information.
You mentioned user state. How can I keep track of the user state during the conversation?
Since it looks like you're using the dialogflow-fulfillment library, the easiest way is to store your state in the parameters in a Context with a very long lifespan (or that you keep renewing).
So the first time your fulfillment is triggered, you can check the Context. If the Context or ID aren't there, then you would generate a random user ID and store it in the Context. Subsequently, you would use this ID to look up the user's information in the real time database.
If I'm doing this work, do I need the database?
Nope! If you are just storing a little bit of information about the user, and the information will just last the lifespan of the conversation, you can store all of it in Context parameters directly. You do need to make sure that these parameter names don't conflict with any parameters that your Intents have, but otherwise these will last las long as the Context does.
If you need to store information about this person in between conversations, then you will need to look into other methods. There is a User ID available for Actions, but this is deprecated and scheduled to be removed. There are also session storage and user storage fields that the Assistant makes available, but these are a little tricker to use using the dialogflow-fulfillment library if you don't need them.

How do I pass a unique identifier to a SignalR client/Server connection?

I am looking at using Signal R for my system
Each user of my system watches a small set of data.
For example, Fred smith (UserID 1) may want to know the price of Gold
UserID 2 wants to know the price of Gold and Silver
Throughout the day there will be hundreds of prices passing through the market
As a new price comes through my system, I am thinking of looking at the users logged in and seeing if any of them care about the price that has come in
If the user cares, I want to send the price to the client instance
I dont want to notify all Signal R clients when every price comes in as that would be too much data!
I am assuming this relies on being able to store something generated client side then passing it through with the connection to the hub
Does Signal R support this? I cant see anything obvious?
I have complete control over my hub.
At present, I plan to write data into a database which I use SQL dependancy to trigger the hub into action
I am using Signal R within MVC 5
Cheers
Paul
Possiblity A) Use Groupping mechanisme of signalR
I suggest you to create a group for each "item" (gold, silver,....).
In the case a user logs in, you should look in which items he is
interested and subscribe for these groups.
(Groups.Add(...) in your hub methode)
So in the case a the value of a item changes, you can send the new
value to all subscribers (clients which are interested to a group)
Clients.Group(groupName).newItemValue(YOURIDEMID, YOURNEWVALUE);
More details about groupping with signalr you will find here:
https://learn.microsoft.com/en-us/aspnet/signalr/overview/guide-to-the-api/working-with-groups
Possiblity B) Handle by yourself
In the case a client connects to the server save the id of this client. Also go to your database and show the interested items for this client. --> Finally you should have a dictionary which contains the ids of connected clients (id) and as value a list with the interested items.
In the case a value of an item changes you iterate through all connected clients and search clients which are iterested about that item. Finally send them the new value.

'Assigning a player in multiplayer game' firebase example is not very scalable or is it?

In the firebase example (https://gist.github.com/anantn/4323981), to add an user to the game, we attach the transaction method to playerListRef. Now, every time firebase attempts to update data, it will call the callback passed to the transaction method with the list of userid of all players. If my game supports thousands of users to join at a time, every instance this method executes, the entire user list will be downloaded and passed which will be bad.
If this is true, what is the recommended way to assign users then?
This is specifically what Firebase was designed to handle. If your application needs to actually assign player numbers, this example is the way to go. Otherwise, if the players just need to be in the same "game" or "room" without any notion of ordering you could remove the transaction code to speed things up a bit. The snippet as well as the backend have handled the number of concurrent connections you've mentioned—if you're seeing any specific problems with your code or behavior with Firebase that appears to be a bug, please contact us at support#firebase.com and we can dig into it.

Architecture that displays messages (like downtime) in application

I'm thinking of a architectural way of displaying messages in our application (Flex-Asp.NET-SqlServer), mostly messages that announce for instance a downtime.
Currently I was thinking of creating a table FlexMessage that holds the name of a message (based on that name I now where to put in Flex) and the value (the message itself). As a result however, someone will have to create these messages and also delete them when they are no longer valid. So, thinking further, I thought of creating messages having a startdate and enddate, so an interval in which they need to be displayed. Like this, someone could login to the management part and create a message that needs to be displayed from a certain date until a certain date.
I could also hardcode it in the Flex Application, but that would mean putting a new build online (of the swf) each time something changes with a certain message. No good idea I guess.
Is there a better way for this that I haven't thought about?
One way to do this is to place your messages in an RSS feed, then read that feed from the Flex application.
There is an example of how to do this here: http://www.artima.com/weblogs/viewpost.jsp?thread=23819

Resources