AWS SNS Publish to specific User via Cognito Identity ID - amazon-web-services

What I'm trying to do here is sending a notification via SNS and APNS when a specific user is part of a newly added DynamoDB Item. I want to send it to the users Cognito Identity ID, not to device token.
So Lambda should be triggered when the item is added and then go through a list of Cognito Identity IDs, which is also part of the item.
Then Lambda is supposed to publish the push notifications to each Cognito Identity ID.
All the devices are registered as endpoints within sns. I also keep the Cognito Identity ID in the "user data" row for the endpoint.
But i didn't find a way to send notifications directly to a Cognito Identity ID. Do i have to add a topic for each user and send the notification to that topic? Or do i have to store another DynamoDB table to map Cognito Identity IDs to device tokens? It would be great if someone knew an easier and not too expensive way!
Thank you!

If you are sending Push Notifications via SNS to APNS or GCM then you first need to create an SNS Platform Endpoint for each device token registered for Push Notifications. Once you have an SNS Endpoint, you'll need to map that endpoint with the Cognito Identity ID in the user table or another mapping table.
When a new item is added to DynamoDB, the event handler (Lambda) will need to map the incoming Cognito Identity ID to the SNS Platform Endpoint in the user table and then it can direct publish to that one endpoint.
You do not need to create an SNS Topic for sending Push to individual endpoints.

Related

Difference between a device subscribing to an SNS topic, and a lambda function subscribing to a topic?

Im currently trying to design a scalable push notification service, which can send notifications to 5-10 mil users in a very short time. I came across two AWS related architectures which got me confused.
Use case: Send a notification to all the users.
1) Each device subscribes to an SNS topic, and if we want to send a push to all users, we just publish to the topics endpoint. And SNS handles the rest(sending to the million users)
2) Lambda functions are subscribed to SNS topics. We send a message to an SNS topic containing all the device tokens/batches, and then lambda calls APN/Firebase endpoints.
I fail to see in what case the second architecture would be beneficial compared to the first?
Mobile push notification :
sns endpoint will created based on user device token and you will get device token from Adm,Fcm,etc like push notification platform sdk and you can trigger push notification to perticular user based sns endpoint because each device have different endpoint and it created user device token and you will have track user device token and endpoint and userId and you can able to see aws sns mobile push notification console
1) you can create manually also
2) you can create endpoint using programmatically
you can refer below sdks to create via code https://docs.aws.amazon.com/sns/latest/dg/mobile-push-api.html
Lamda push notification
You can create sns topic in sns console and you can subscribe which lambda you want deliver notification
basically if you want connect one lamda to another lamda you can use those case
example 1:
you have micro service for sending otp to user and micro service deployed in different lambda and application recives sending otp request your application main lamda and now you need call otpservice lamda so you can create one sns topic and under subscription you can subscripe otp micro service lamda so main lamda will trigger otp service sns endpoint it will deliver notification micro service lamda

Use cognito login instead of certificates to authenticate and subscribe to aws IoT MQTT topics?

I'm new to learning AWS and I'm trying to figure out if my use-case is possible. I want to create a mobile app where the user can login (email/facebook/google etc.) and then subscribe to a few MQTT topics on aws IoT to receive realtime sensor data for a gardening system. There are many tutorials on AWS that show you how to do this
(prime example: https://github.com/awslabs/aws-sdk-android-samples/blob/master/AndroidPubSub/README.md)
but all of them require you to download certificates, insert app IDs, secret keys etc. in the code/keystore itself. I'd really like to avoid all of this and just use the login as all the authorization you would need to subscribe to these topics.
is this possible? or do I need to build some custom system?
Short answer, Yes, it is possible. To do that you should do the following:
Create Cognito user pool. User Pool ID and App client id will be used in the next step. You can find more information here.
Create Cognito Identity pool. Under Authentication Providers you should give User Pool ID and App client id, more information here. When you create this, it will create two Roles for Authenticated and Unauthenticated users in IAM. You should add IoT access permissions (Connect, Publish, Subscribe and Receive) to those roles.
On client side (your App), after choosing your preferred AWS SDK (Android, iOS, React, JS, etc.) and configuring User pool ID, Identity pool and App client ID you should first authenticate the user by sending the user information (usually Email/Username and Password) to the Cognito user pool. In return, you will get some tokens.
Among those IdToken (JWT) will be sent to the Identity pool and in return you will get User Identity ID along with credentials (accessKeyId, secretAccessKey, sessionToken) needed to access AWS other services like IoT.
Last step would be using aws-iot-sdk for your App along with those credentials to publish and subscribe to your IoT topics. You can find more information about aws-iot-sdk here.

Cognito Identity Id in AWS IOT event handler

I have an AWS Lambda function called on "subscribe" IOT event. Client subscribes to IOT with Cognito credentials. Is it possible to get Cognito Identity Id in the Lambda function?
I think you can get the Cognito Identity ID from the identity property (in case of noe.js runtime) of the context parameter (context.identity) as explained here.
Also, I don't really understand the use-case of Cognito Identity ID. I think you should be able to uniquely identify your devices using clientId property of the MQTT message.

Getting user from SNS EndpointAdded Event

I'm trying to associate my user's Cognito identity with the SNS endpoints they create when registering for push notifications. I've created a Lambda functions connected to the SNS application's EndpointAdded topic. It is fired whenever an endpoint is created, but it does not include any information I can see that I can use to associate the endpoint to a user.
I see many examples where people are adding the user ID as custom user data, but this allows any user to sign up for any other user's notifications. Is there a more secure way to make this association?
If you front registering the endpoint with Lambda or APIGateway and you use SigV4 credentials vended by Cognito to make the call, the context passed in will contain the Cognito Identity Id extracted from the credentials that made the call. This will ensure that the identity id you associate with the endpoint hasn't been tampered with.

SNS Batch Publish

I see AWS publish API for sending push notifications to devices.
http://docs.aws.amazon.com/sns/latest/api/API_Publish.html
According to:
https://aws.amazon.com/blogs/aws/push-notifications-to-mobile-devices-using-amazon-sns/
We can
"Send messages directly to a specific device by calling the Publish function with the device’s ARN. You can easily scale this to handle millions of users by storing the endpoint ARNs in Amazon DynamoDB and using multi-threaded code on the server."
If I want to send push notifs to 100K users (who haven't registered to a specific topic), is there a multi-publish (or batch-publish) API, where I don't need to call the "Push notifications" API for every single user?
probably not. the devices need to be registered (i.e. for SNS you actually have to create the endpoint for each device).
After you have the endpoint you can subscribe them to either one or multiple SNS endpoint and start publishing notifications through them.