How to update properly GCM registration id in application - push-notification

I'm trying to create an app that uses push notifications. I have done all the work in both 3rd-party server and application development and the notifications are sent successfully.
In this certain part of the application, the user will be registering to GCM and 3rd-party server, through a specific service, and then uploading to the 3rd-party server the football games that he wants to be notified when they are completed.
The problem that I'm facing is that when I uninstall the app, the GCM servers (when I'm sending a message) don't respond with the NotConnected error. So when I re-install the app the GCMRegistrar gives me a new registration id and this makes my server to have two different registration ids for the same user.
Although I can solve this problem with the help of the canonical id. In particular Google says
"canonical_ids": 1
"results": [{ "message_id": "1:2342", "registration_id": "32" }]
success, but the registration ID should be updated in the server database (from 23 to 32)
So if I listen to google's advice, with changing the registration id to the older (working) one, this will cause afterwords the application, with the new registration id, to send the football games to the server with this specific new registration id and the server will not understand where to store this info.
I know that a registration id is not a user's id but a registered device's id.
My first thought is to let the server have different registration ids. So when I get a canonical id, I will ignore it. I don't like this idea though...
My second thought is when I change the registration id to the older one, to update it somehow into the app...
Can anybody tell me which sounds better to my situation? This is the first time that I use push notifications...

So if I listen to google's advice, with changing the registration id to the older (working) one
That's the opposite of what Google tell you to do. They encourage you to remove the old ID from your DB and keep only the new registration ID.
Here's the relevant quote :
Canonical IDs
On the server side, as long as the application is behaving well, everything should work normally. However, if a bug in the application triggers multiple registrations for the same device, it can be hard to reconcile state and you might end up with duplicate messages.
GCM provides a facility called "canonical registration IDs" to easily recover from these situations. A canonical registration ID is defined to be the ID of the last registration requested by your application. This is the ID that the server should use when sending messages to the device.
If later on you try to send a message using a different registration ID, GCM will process the request as usual, but it will include the canonical registration ID in the registration_id field of the response. Make sure to replace the registration ID stored in your server with this canonical ID, as eventually the ID you're using will stop working.

Related

Managing Session Cookies, from Firebase Authentication, with Redis

I am using Google Firebase Authentication to handle user management for my web application.
Specifically, I am using managed session cookies. The problem I am running into is figuring out how to associate each session with a corresponding user.
For example, I would have two separate tables:
User - Stores personal information such as name, email, password, etc
Account - Stores account related information such as posts, friends, etc
I was thinking of using Redis as a key-value store for this situation and the flow would work something along the lines of this:
User enters credentials
Credentials gets verified by Google's backend
User receives ID token
User sends ID token to my backend along with user id
Google's backend creates a session cookie
Backend would store the session along with the user id into Redis
Whenever user hits a protected endpoint that requires user id, a call to Redis would be made
I thought this might work because, within my Flask API, if I print out the type of the session cookie, the value is of type string.
I was wondering if this is an overkill, or if there is a better alternative to achieve what I want.
After much research and discussions with peers who work in the software industry, I have decided to use the strategy outlined in the question.
Feel free to comment if you have anything else to add.
Cheers.

Is it really necessary to update the subscription on every page load?

I'm currently working on a web app which will allow a user to subscribe to push notifications. We'll store the subscriptions in a database table mapped against the user's ID and when a notification needs to be sent, we'll look up the user's subscriptions and send the notifications.
I've been following this guide:
https://developers.google.com/web/fundamentals/codelabs/push-notifications/
All is going well, but something just doesn't feel "right".
On every page load, the service worker is registered, then it checks if they're already subscribed, then even if they are it calls updateSubscriptionOnServer() which contains the following comment:
// TODO: Send subscription to application server
This effectively means that every page load is going to be attempting to write the same subscription back to the database. Obviously we'll handle that in the application, but it doesn't seem ideal.
With the Web Push API, is this the expected approach?
Many thanks
Yes it can be useful to send the subscription to server on every page load:
The user may have changed permission from blocked to granted (or default) in the browser settings, so you want to create the subscription and send it to the server
The subscription endpoint may change for different reasons, so you need to make sure that the current endpoint is sent to the server (the previous endpoint will return 410 Gone)
A compromise between the points above and performance can be to send the subscription to the server only on given pages (e.g. homepage).

Stop concurrent multiple client's access to the ASP.NET Web API and ASP.NET Identity 2.1

Problem statement:
Hi. I have some secured data which I want to expose through Web API and ASP.NET Identity mechanism. I want to use out of the box classes of ASP.NET Identity. I take a payment manually and change a value in the table. But there are cases where the user will share his username + password with some other guys so that the others can access the same content without paying anything.
Work plan:
So, I have extended the AspNetUsers table with a column named ApplicationToken (varchar). After successful login, I want to generate a token, update the field of the user's row in the table, and add this value as a claim information and send back to the client app. Now, when the user requests for a paid content, my client app will send the token also. So, somewhere in my server side codes, I need to check this ApplicationToken with the Database token value. If both are equal, I allow the request to proceed, otherwise I will send 401 Unauthorized and tell them to login again.
Implementation options:
After studying and searching, I found the below options to implement:
Create Custom Authentication Filter attribute so that I can grab the claims send from the client and do my required validation
Create a base class of the secured API and get the claims there and do my required validation.
Go for different Jwt based implementation where I should have access in both issuing and checking the Json Web Tokens.
If you have any other options, I would be very glad to hear those.
My question is, which approach is better to proceed. I have enough time to implement, so time is not a factor here. Thanks.

Signal R for notifying the single authenticated user

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!

Persisting data cross domains?

I have 2 applications, each in different domains. When a user comes to the first application, clicks a link, the user is sent to the second application.
My problem is as follows: I need to persist a sessionId from the first application to the second application. Simple enough but here's the catch. I can't use query string and I can't use cookies(since in different domains). I was thinking, is there a way to insert custom values into HTTP Headers or set some form values on an intermediate page which would then POST to the second application? So the process would be as follows:
User clicks a link on the first page, this takes the user to an "intermediate" page, this "intermediate" page sets a sessionId value in the form or http Header, then the "intermediate" page sends the user to the second application via a POST where the app will have the sessionId.
I can't use a Server.Transfer since the app is not on the same server. Help?
This is how Microfot tried to do it Does Issuing Passports Make Microsoft a Country?.
You could try and make a secure SOAP or XML request with a secure token referencing a session id you stored for the user in a shared database. You could then load the user's session based on that session id stored in the db if a match is found.
One way that you could do it is to use webservices. Before the user is to switch sites, you could give the user an unique authentication token that has been agreed upon prior to leaving.
Another thing you could do (this is not a great solution, but it works) is to use frames, and to send the child frame information through javascript (login information). I really don't like this method, because it presents so many problems that its best avoided.
What I mean:
Web services: Communicate with the other site to say "this user is currently logged in here," you can do this at login (depends how much you trust the other domain), or you can do it when the user requests to leave
Giving the user an authentication token: You can post it as a form element. Or if you had an agreement with both domains you could send it to a URL that could later be interpreted as a rediection service+authentication token confirmation portion. I.E.: domain.com/page/token+pageid-mixture
Use OpenID. It's designed for this purpose (common authentication to web sites on multiple domains). The protocol's been under development for years and has probably encountered and solved a lot of the problems you'd be likely to run into if you roll your own solution.

Resources