I have a feature where I get a list of device endpoints and I need to send push notifications to all the devices in that list. The list is dynamic in the sense that it can consist of any number of users from my user base. Also, the size of the list can vary from anywhere between 1 to 10000+ so efficeincy becomes important.
I've read the SNS docs and scoured through the internet but all I could find was that either to loop over all endpoints and publish messages individually (which can be highly inefficient for my use case), or some solution about creating a topic and publishing to that topic so that all subscribers will receive the message (can't do this because my list of users will keep changing).
Maybe I'm missing something here or maybe I was lacking in my research. Any help or insight is appreciated.
I found a solution to this to this but unfortunately it has a couple caveats that prevent me from using it. I'll explain the solution first and then discuss the caveats.
The idea is to create a SNS topic and subscribe all my users to that topic with a unique filter policy so that I can target the users however I want to.
Whenever my api receives a mobile device endpoint for a user, I subscribe that to my topic with the user's Id as a filter policy which will always be unique. It would look something like this - { target:[user-1234] }
1234 being the Id of that user. Also, I unsubscribe that endpoint from the topic whenever that user is no longer active.
On sending a message to a group of users, I use Message Attributes to target the users. The message attributes are to be added in the form of a string array that would look something like this [\user-1111\, \user-2222\, \user-3333\]
. This would publish the message to only these 3 users.
From my tests this took about 3 seconds to send messages to 1000 users. Its not great performance but it was much better than what we were expecting.
Here's a poc that I did to test this out.
Caveats
As per the aws docs, each topic has a service quota limit of 200 filter policies. Since this solution uses a 1 filter policy for 1 user, this would only work for 200 active users. It is possible to request for a quota extension from aws but they hold complete autonomy on whether to grant the request or not. I got an increase of 1000 filter policies per topic, so it'll work for now but it would fail our future scaling plans.
In the end I implemented a solution to send a message to individual device endpoints using a Parallel.ForEach loop. This approach took about 12 seconds to publish a message to 1000 users (much worse). The initial idea was to use a separate service for sending push notifications but could not be implemented due to time crunch; we'll probably implement that in the next phase.
Note: The answer provided by @codeninja.sj is much more elegant than the solutions I've discussed here and I feel it would also scale better. Unfortunately, I could not convince my team to implement this solution.