I've implemented a Web Push API with the help of this Google tutorial: https://developers.google.com/web/fundamentals/getting-started/codelabs/push-notifications/
The tutorial includes a method, which could be used to send the subscription to a backend server:
function updateSubscriptionOnServer(subscription) {
// TODO: Send subscription to application server
...
}
I want to store the subscription together with a user identifier, so I can choose which users I want to send a notification. Now I'm wondering, which part of the subscription I've to store in the database. My subscription objects look like this:
{"endpoint":"https://fcm.googleapis.com/fcm/send/...","keys":{"p256dh":"...","auth":"..."}}
Should I just create a table "Subscription" with columns (Id|User_Id|Subscription), which includes the whole JSON subscription? What is best practice for that? Is the JSONs validity unlimited? Which field can I use to identify a subscription in case of unsubscription?
The API call from your back-end / application that triggers a push message to a user's device. The service worker JavaScript file that will receive a "push event" when the push arrives on the device. It's in this JavaScript that you'll be able to show a notification.
A push subscription is a message delivery context established between the user agent and the push service on behalf of a web application. Each push subscription is associated with a service worker registration and a service worker registration has at most one push subscription.
There are two protocols http and xmpp which you can use to send message to GCM server.
To allow anonymous web-push-users to use our service, we've come up with the idea to hash the subscription and use the hash as the backend's primary key (id).
// pseudo-code
const id = hash(subscription);
https.post(`${SERVER}/subscription/${id}`, subscription).then(...);
As I understand correctly, the subscription does not change over time and therefore, the hash is a constant. Collisions are not to be expected since every subscription is unique and you may choose an appropriate hash function (e.g. SHA-512).
You can then re-validate the subscription in your Service Worker or handle pushsubscriptionchange
events as long as you can access the original subscription and re-create the hash/id.
This should cover most of the cases. But still, when sending the push-notification through Google's and Firefox's push-servers, you'll still need to respect the response codes (HTTP 401
) for invalid subscriptions and remove them from your database.
See Javascript Crypto functionality for available hash-functions. Supported by FF and Chrome.
Storing your Subscription in the database
Your database should look like if you are using a document db:
userId: {type:String, required: true},
endpoint: { type: String, unique: true},
keys: {
p256dh: {type: String},
auth: {type: String}
},
userAgent: {type: String}, // optional, just an additional tracking field
deviceId: {type: String} // just additional tracking fields
If you are using a relational database you can store the keys
part in individual columns or use a JSON
type column.
The main thing to know is that webpush.sendNotification(...)
takes an object with the following interface:
export interface PushSubscription {
endpoint: string;
keys: {
p256dh: string;
auth: string;
};
}
which means basically these are the properties your database will need to keep track of subscriptions. You may choose to add userId, and others for your own specific use case
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With