I would like to know if is possible to create a chat for private conversation like gmail chat or hotmail..
How can I ensure that only client A talks with client B?
How can I ensure that only logged clients can talk?
Sure, you can create a unique "Group" each time a user initiates a chat with another user (or set of users). Then when you send messages to that group only those users would receive the message. You could also layer more security in front of sending messages to a group to ensure that the person sending the message is allowed to send a message to that group.
Try this application for Private chat with SignalR
Description of Application:
http://www.aspbucket.com/2016/03/implement-of-private-one-to-one-chat.html
Download link
https://github.com/shivam01990/SignalR-private-one-to-one-chat
Look at ChatWithTracking in Basic chat sample, that's a great starting point for IM setup
p.s: updated the link; using a search query in case they change the repo structure again
Each client connecting to a hub passes a unique connection id. You can retrieve this value in the Context.ConnectionId property of the hub context. If your application needs to map a user to the connection id and persist that mapping, you can use one of the following:
In-memory storage, such as a dictionary
SignalR group for each user
Permanent, external storage, such as a database table or Windows Azure table
http://www.asp.net/signalr/overview/hubs-api/mapping-users-to-connections
Related
I want to use Firebase Auth for my user login/registration process. Everything else should be handled by my own backend (spring boot app + postgres db).
Now I'm asking myself how I can synchronize a new created user to my user table in postgres. I thought about the following:
REST call through client - Everytime I get a success event from the firebase sdk I call an additional request to my backend which sends uid, username etc.
Problem: What if my backend call fails but the register process was successful ? That would lead to an inconsistent state since (at least thats what I understanded) I can't easily rollback. That would lead to situations where a user can login into my app without my backend knowing the user. This would crash/ invalidate all my following queries (e.g. search after user xyz would lead to no result even though he/she exists)
Check the existence of the user in the postgres database
Here I would query the uid from the database (which I got from the jwt) and create a new user if it doesn't exists in every incoming request.
Problem: The user query is a unnessecary overhead for every incoming request.
Trigger with cloud functions - When I understood it right firebase auth is firing events when a new user is created in cloud functions. This could be used to make the external api call.
Problem: I dont know what happens when my external rest call fails at this point. Can I rollback the registration ? Will I be ever catch this event again ? I also proably would have an eventual consistency situation, since I dont know when the cloud function triggers. Furthermore I would prefer not to include cloud functions to my stack
Is there any way how I could do this in a transactional manner ? Did anyone else tried is using sth simular ?
Thanks for every help!
The easiest way is actually to not synchronize auth data, but instead decode and verify the ID token of the user in your backend code.
This operation is (by design) stateless, although Firebase's own backend services often implement a cache of recently decoded tokens to speed up future calls with the same ID token.
Apparently, I finally came up with a different solution:
Register user per Firebase SDK (e.g. with email + pw method)
Make a post-call to my own registration api including the resulting uid from the previous step and some metadata
API creates a new user including a column with the UID + Fetches the firebase token of the user and adds an internal claim that references to the internal Postgres UUID via Admin SDK.
Frontend gets the created user and hard refreshes (very important, since the previously fetched token won't contain the newly added claim !) the firebase token and verifies that it contains the token. If it does -> everything is cool, if not some oopsie happened :) That will require a request retry.
Later when you start your app you can just check if the passed token contains the custom claim, if not open the sign up/sign in page.
Every endpoint except the one for registration should check if the claim is set. If not just forbid the request.
How to set custom claims:
https://firebase.google.com/docs/auth/admin/custom-claims#set_and_validate_custom_user_claims_via_the_admin_sdk
You can use the Firebase Admin SDK to create the user account from your back-end instead of from the client.
So first you create the user in your database, then grab the ID and use it to create a user with the same ID in Firebase.
If all goes well, send a confirmation to the client and sign it in using the same credentials they entered.
Why not creating an endpoint in your backend service and call this endpoint when a client side authentication succeeds?
This method should do 2 things:
decode token to get access to Firebase user object (Firebase Admin)
Compare Firebase user with your internal user table. if it doesn't exist you can create it using firebase user object, otherwise do nothing.
This solution allows you to do other nice things as well (Syncing user info between Firebase and your internal db, providing a way to let a frontend know if this user is new or not, ...) at a relative small cost (1 get call per sign in)
The SignalR user session ends after changing the page. A new session opens on the new page.
I need a connection that will continue as long as I log out of Hub.
As far as I know, when you connect the signalR hub server, it will generate a connectionID.
Each new session will use specific connectionid, we couldn't modify the conenctionid when you used the new session.
If you want to let all the tab connect as one user account, you could try to check the username when the connection started and then store the username and connectionid as one to more in the server memory or else.
Then if other user send message to this user, you could get the connectionid according to the username and use Clients.Client(conid).SendAsync method to send the request.
More details about how to achieve it, you could refer to this reply.
I am the new for FCM. Here are some questions about the registration token:
Is the registration token generated by the FCM connection server?
Does the token change periodically in the connection server?
When?
Will it force the onTokenRefresh() in the app to be called?
I have googled for a week but didn't get any details. Please help. Thanks.
1. Is the registration token generated by the FCM connection server?
No. It gets generated by the FirebaseInstanceID. The way I understand the flow of event on first time registration:
The app retrieves a unique Instance ID.
The registration token is generated by calling the InstanceId.getToken().
Developer (usually) sends the token to the App Server.
2. Does the token change periodically in the connection server?
I think the onTokenRefresh() docs pretty much answers this.
Called when the system determines that the tokens need to be refreshed. The application should call getToken() and send the tokens to all application servers.
This will not be called very frequently, it is needed for key rotation and to handle Instance ID changes due to:
App deletes Instance ID
App is restored on a new device
User uninstalls/reinstall the app
User clears app data
The system will throttle the refresh event across all devices to avoid overloading application servers with token updates.
See this part of the docs for more details.
Following is the scenario I want to achieve using signal R.
If sending of email is going on then message will get display
Example: "Sending Email.."
Once email sending is done will show the another message to the same user stating
Example: "Email Sent successfully."
How I will achieve this with Signal R and sending the notification to the one user only.
Read the post which are saying use Connection Id but that will be changing not a fix
I want to do this for the Authorized user only or we can say with static userid.
I see two different approaches to the problem, with two different solutions. Either the server keeps track on which connectionId(s) that belong to a particular user. Or the client lets the server know which connectionId to use.
Option 1: Server knows how to map user to connectionId(s)
Firstly you need to map each user to the connectionId(s) they have. Bear in mind that the user could have several connectionIds as he/she could be logged on in multiple tabs or browsers. On the server it is difficult to distinguish between connections so when the user sends an email, it is easiest to notify on all connections that belong to that user.
There are several ways to keep track of users connectionIds. Here is a good walk through. In your case I think the UserID provider option would be a good fit, as it's easy to implement and sufficient if you only want to send updates to the current user.
Option 2: Client notifies server on connectionId to use
Another approach could be to include the connectionId in the call to the server. That way the server knows which connection to report back to. You can get the connectionId in Javascript (as described in this answer) using:
var c_id = $.connection.hub.id
Hope this helps!
I have created web chat application using signalR. When user is logged in, user can open only 3-4 tabs and each time different connection ID is generated. I want that when we open new tab or refresh the page new connection id should not be generated. I want to use the existing connection id. For that I tried to implement the LocalStorage variable to store the hub connection.
But Problem is i am unable to parse the value of localstorage variable.
Can Anyone give me the solution to my problem or can anyone give me any other solution to the problem?
I have already tried this http://kevgriffin.com/maintaining-signalr-connectionids-across-page-instances/ but it dosen't work for me
If user is authenticated you can store different connectionIds in the HashSet. The key for the HashSet will be the user's name.
http://www.asp.net/signalr/overview/signalr-20/hubs-api/mapping-users-to-connections
You can use this method even if you are not authenticated. In this case you can use SessionId instead of username.
EDITED:
I have found another method. In this article Alex Ford advices to limit your connections to 3.