AWS IoT Core Integration in Mobile IoT Applications
AWS IoT Core — managed MQTT broker with X.509 certificate authentication, access policies via AWS IAM/IoT Policies, and ability to scale to millions of devices. Integrating it into mobile app isn't hard but has several places where almost everyone makes mistakes.
Authentication: What to Choose for Mobile Client
AWS IoT Core supports three auth methods for mobile: X.509 certificates, AWS Cognito Identity Pools, and SigV4. Certificates are for devices, not mobile apps: storing private key in app is unsafe, rotation is complex.
Right path for mobile clients — Cognito Identity Pool + IoT Core. User logs in via Cognito User Pool (or federated auth via Google/Apple), gets temporary AWS credentials via AssumeRoleWithWebIdentity, and already with these credentials connects to IoT Core via aws-iot-device-sdk or native MQTT over WebSocket.
On Flutter use amplify_auth_cognito for auth and mqtt_client with custom WebSocket endpoint:
wss://[endpoint].iot.[region].amazonaws.com/mqtt
Sign WebSocket Upgrade request via SigV4 — headers X-Amz-Security-Token, X-Amz-Date, Authorization. aws_common from Amplify SDK knows how to do this.
On React Native — AWS Amplify with @aws-amplify/pubsub, which under the hood uses MQTT over WebSocket with automatic SigV4 signing.
IoT Policies: Where Rights Are Cut
IoT Policy is separate from IAM. Even if Cognito role has iotdata:Publish, without IoT Policy on iot:Publish for specific topics requests return 403. Typical policy for mobile client:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["iot:Connect"],
"Resource": "arn:aws:iot:region:account:client/${cognito-identity.amazonaws.com:sub}"
},
{
"Effect": "Allow",
"Action": ["iot:Subscribe", "iot:Receive"],
"Resource": "arn:aws:iot:region:account:topicfilter/home/${cognito-identity.amazonaws.com:sub}/*"
},
{
"Effect": "Allow",
"Action": ["iot:Publish"],
"Resource": "arn:aws:iot:region:account:topic/home/${cognito-identity.amazonaws.com:sub}/*"
}
]
}
${cognito-identity.amazonaws.com:sub} — policy variable substituting Cognito Identity ID. Each user sees only their devices. Standard multi-tenant IoT pattern.
Device Shadow: State Without Persistent Connection
AWS IoT Device Shadow — key feature for mobile apps. Device can be offline but Shadow stores its last known state. Mobile client writes to desired, device reads on reconnect and updates reported.
In practice: user turned off light via app. Command goes to Shadow desired. Device was offline 10 minutes — on reconnect read delta and executed. Without Shadow would need maintain command queue yourself.
For reading Shadow from mobile — REST API or MQTT topics $aws/things/{thingName}/shadow/get. Update — publish to $aws/things/{thingName}/shadow/update with {"state": {"desired": {"power": "OFF"}}}.
Rules Engine for Notifications
AWS IoT Rules trigger Lambda, SNS, SQS by conditions from MQTT. For push: IoT Rule → Lambda → SNS → Firebase Cloud Messaging / APNs. Cleaner than keeping persistent MQTT connection only for notifications.
Typical Problems
Reconnect storm: 1000 devices reconnect simultaneously after network failure → IoT Core throttling → avalanche of errors. Solution: exponential backoff with jitter in client code, mqtt_client doesn't do it automatically — implement yourself.
Endpoint throttling: iotdata endpoint limits to 20 transactions per second per account by default. For production loads request limits via AWS Support beforehand.
Process and Timeline
Cognito + IoT Core + IoT Policies + basic integration setup — 1–2 weeks. Device Shadow, Rules Engine, notifications — another 1–2 weeks. Full integration with real devices and load testing — 4–6 weeks. Pricing calculated after assessing device count and message frequency.







