Notifications System idea - ruby-on-rails

I am trying to integrate a notifications system into one of my rails apps. I am using PostgreSQL as my primary database. I am considering to use redis for supporting the notifications system.
However, I have some questions regarding the usage of redis:
Handling different types of notifications(Eg.: User commented on post, liked post, tagged in a photo etc).
If I have a namespaced key in redis for notifications per user, how to manage the load, meaning setting the limit of number of notifications.
Store notifications as a string or use hash(Eg.: User A commented on User B's post)
A PubSub feature for notifying all other users as well(Eg.: If User A comments on a post, all users who commented/liked a post must be notified).
Any ideas how this kind of notification system must be designed?

Related

How to identify the customer on a server-sent event for Apple subscriptions?

Implementing subscriptions on an iOS app means we want to handle SSEs in case of subscription status change, as to manage the user's rights inside the service.
The Apple documentation doesn't show an explicit customer GUID.
They provide, in each SSE's payload, receipts, e.g. the latest one.
The question is: how can an API server uniquely identify customers?
Should the API server keep track of every receipt, in an inheritance way?
I.e. should the API persist every receipt, and a link to the previous receipt, up to the first
one that was emitted (which can be linked to a customer through the iOS app the user used to initiate its subscription), and re-trace this history on every SSE?
Per this thread, the applicationUsername service-side UUID (used by apple, for "irregular activity checking") isn't a solution, as it isn't provided in receipts or SSEs. The thread hints that using the transaction IDs is still the best way to identify a SSE, as it is ultimately tied to a user, and it is up to the service to keep track of transactions made by the user on the Apple platform for the given service.
Isn't there an easier, more direct, way, to establish the relationship between a SSE, its apple customer, and the service's user?
After digging for a while and asking around, I reached the following conclusion:
There is only one way to tie a transaction event to a user, and that is by the
restoration mechanism one has to implement on their application.
For this reason, you need to at least keep track of original transaction IDs,
so when the restoration mechanism is triggered on your app, you can check the
currently logged user on your app, and call your back-end with the logged user,
and a list of original transaction IDs.
Usually, when a user subscribes, it is mainly done from within your app, so you
can do this link in a trivial way.
But, because you can "re-subscribe" from the AppStore after a while, without
going through your app, Apple may send a SSE to your back-end which would contain
a new (hence unknown) original transaction ID, since this new subscription is
has a new transaction.
In short,
You need to keep at least a DB of original transaction IDs you receive as SSEs
You need to implement the restoration mechanism as to contact your server every
time the app starts, with the list of transaction IDs / original transaction IDs Apple gives you
You need to accept having transactions stored in your backend without a link
to a user (because the user may have re-subscribed without launching the app yet)

Get user from server to server notification of subscription ios

I am using sever to server notifications of ios https://developer.apple.com/documentation/storekit/in-app_purchase/enabling_server-to-server_notifications.
It is giving me the notifications but there are no information that to which user this transaction belongs or who paid for it, so am I missing something or there are other ways to know?
You can only rely on original_transaction_id. It's unique identifier of subscription. In case you have one subscription group it also identifies your user. However you have to implement your own logic by matching your users with original_transaction_ids.
You can also use ready-to-use solution to handle Apple notifications, like Apphud.

Is there a way to have push notifications for different groups

I want to be able to send push notifications in my app. But i would like to be able to send them to certain categories like country
any way to do this if there is 25-30 different categories
also a way for somebody to pick a category and then get push notifications for that category
I handle sending push notifications myself, the backend receives push keys from the mobile apps after login, this way I can decide which user I want to send push notifications... This way you can decide how to implement subscription and push mechanism yourself, and check if a user has a topic enabled and is in the specified country.
Anyway: more info will get you better responses: ios? android? external push notification service? used frameworks?
Have you considered using Firebase Topics?
Based on the publish/subscribe model, FCM topic messaging allows you to send a message to multiple devices that have opted in to a particular topic. You compose topic messages as needed, and FCM handles routing and delivering the message reliably to the right devices.
For example, users of a local tide forecasting app could opt in to a
"tidal currents alerts" topic and receive notifications of optimal
saltwater fishing conditions in specified areas. Users of a sports app
could subscribe to automatic updates in live game scores for their
favorite teams.
You could simply subscribe/unsubscribe users from the relevant country topic.

Managing PushSubscriptions within shared browsers

Working on ironing out some UX considerations around a push notification system using WebPush and ServiceWorkers. Additionally, this system should gracefully handle multiple users sharing the same browser.
More concretely, I have the following constraints:
1) A user should not be able to see notifications which are not intended for them.
2) The state of a user's push subscription should be opaque to and immutable by other users. i.e. the state of my push subscription should not be based on the behavior/actions of anybody but my own.
Satisfying the first constraint was quite straightforward. I decided to store the currently logged-in user id in IndexedDB and include the id of the intended user within the push payload. It is then straightforward to only show the push notification to the user if those 2 ids match.
However, satisfying constraint 2 has proved to be quite elusive. So far I've tried:
1) One-to-one mapping between users and push subscriptions. This was the first thing I tried, as it struck me as the most natural mapping. However, this ends up falling flat on its face as creating a new push subscription will invalidate the subscription for the previous user, thus requiring the original user to create another subscription on subsequent logins, thus failing the second constraint.
2) Shared push subscription. This has the benefit of not invalidating the push subscriptions, so subsequent logins for the original user will behave as expected. However, none of the subsequent users will actually need to grant permission to the browser, thus failing the second constraint.
3) Even if I was able to get something working with one of the above 2 options, there is still nothing preventing another user from simply going to the browser settings and disallowing notifications, thus nuking all push subscriptions. However, I imagine that this is just something I will have to live with that will have no elegant solution.
I'm certain there have been many brilliant minds working on the above problem, so I'm all ears with regards to how constraint 2 above has effectively been satisfied.
Thanks.
I had the same problem when I was developing Pushpad. We tried different solutions and some of them, such as the many to many relation between users and browsers, became a nightmare very soon. So I would recommend the following approach, which proved to be the best one for us.
Each subscription (endpoint) is a device (browser) and can be associated at most to one user at a time. Whenever possible try to keep data associated to users and not to devices. In this way a subscription (endpoint) can be transferred to a different user and you don't loose data when the endpoint expires or gets replaced. Then when you need to send a notification filter your audience based on the user data, find the recipients and send the notification to the associated devices.
The only data that you may want to associate to devices are device preferences and device preferences are global to all the users that use that browser. This is consistent with the fact that the browser permission (allow / block) is global to all users.
The above solution partially meets your requirements:
1) A user should not be able to see notifications which are not intended for them.
Yes:
when a user logs out you can remove the association between the user and the device
when a browser (user) logs in with a different account on your website you associate the device to the new user (and you remove the previous association)
2) The state of a user's push subscription should be opaque to and immutable by other users.
Yes, because you don't keep data associated to the device. You associate data to the users in your database.
There is no way to satisfy both constraints. You will need to choose either the one-to-one mapping (1) or the shared push subscription (2). You cannot use the browser to deliver your push notifications and at the same time expect certain behaviour (w.r.t. permissions, nuking) from that very same browser...

How to use Non-Renewable Subscriptions in multiple devices?

I'm implementing an application with Non-Renewal Subscriptions. For that i have referred many sites and most of the answers that i found as like,
We need to manage the expire date by ourself in our server side/local, once you verify a receipt with Apple.
We can implement authentication module as optional to share use the Non-Renewal Subscriptions across multiple devices.
Actually my application doesn't have authentication modules like registration/login to track user on multiple devices. So How can i able to use the Non-Renewable in multiple devices without allowing user to register/login. Do we have any common field to trace the user on multiple devices without authenticating them.
Thanks in advance, Can anyone please give any suggestions to handle this scenario.
You will need some server side support. If you are fine with receiving unauthenticated traffic, you can use the original transaction id. For each subscription purchase you make for a given Apple Id, that purchase will have a unique original transaction id (in the receipt).
If the user initially purchases the subscription on device A, let's say they get back a transaction id of 1234 (note this is not the format, I am just using this as an example). Now the user goes to device B and makes the same purchase. Note this is a subscription, so Apple will already know the purchase was made for that Apple Id. It will indicate the subscription was already purchased, but will let the person still "purchase" (they won't be charged). Upon this, they will get a receipt. This receipt will have the same transaction id.
So here is where your server would need to tie the two together. You would most likely use a UUID, such as [[UIDevice currentDevice] identifierForVendor]. Now your server will know that transaction id 1234 is used by device A and device B.
You can choose how to send this information. You can either send it by way of the receipt (in which case your server will need to unpack it to get the transaction id) or the app can do it for you.
You should do what you can to increase security measures. For example, the method above could be easily spoofed.

Resources