Configure Cognito Sync to share user data between devices
This is the scope of the AWS DVA, which is about development using AWS services.
Cognito Sync can be used to share user data between devices.
This time, we will use AWS SDK for JavaScript v3 to operate Cognito Sync.
We will be using Cognito Sync, but it is currently recommended to use AWS AppSync instead of this feature.
If you’re new to Amazon Cognito Sync, use AWS AppSync. Like Amazon Cognito Sync, AWS AppSync is a service for synchronizing application data across devices.
Amazon Cognito Sync
Environment
Create an S3 bucket and enable the static website hosting feature.
Prepare content by placing HTML files inside.
Use the Cognito ID pool to grant access to Cognito Sync to users who have successfully signed in.
To validate Cognito Sync, we will create a function to store and share data about the background color of the browser. Specifically, we will perform the following steps:
- launch a browser, sign in to your personal page, and save the background color.
- launch another browser, sign in to your personal page again, and retrieve the background color in your browser.
CloudFormation template files
We will build the above configuration using CloudFormation.
In addition to the CloudFormation template, browser scripts, etc. are placed at the following URLs.
https://github.com/awstut-an-r/awstut-dva/tree/main/03/001
Template file points
We will cover the key points of each template file to configure this environment.
Grant temporary permissions to access Cognito Sync
Let’s check the identity pool itself.
The point is the IAM role for the privileges to be granted to the authenticated user.
Resources:
IdentityPoolAuthenticatedRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: sts:AssumeRoleWithWebIdentity
Principal:
Federated: cognito-identity.amazonaws.com
Condition:
StringEquals:
cognito-identity.amazonaws.com:aud: !Ref IdentityPool
ForAnyValue:StringLike:
cognito-identity.amazonaws.com:amr: authenticated
Policies:
- PolicyName: IdentityPoolAuthenticatedPolicy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- cognito-sync:*
Resource:
- !Sub
- "arn:aws:cognito-sync:${AWS::Region}:${AWS::AccountId}:identitypool/${CognitoAud}/identity/${CognitoSub}/*"
- CognitoAud: ${cognito-identity.amazonaws.com:aud}
CognitoSub: ${cognito-identity.amazonaws.com:sub}
Code language: YAML (yaml)
Create a policy that allows the signed-in user to access Cognito Sync. You can create the policy by referring to the AWS official page IAM Roles and Role Trust and Access Permissions.
Browser Script
Use JavaScript to implement Cognito functionality after sign-in.
For instructions on how to create a browser script using AWS SDK for JavaScript v3, please see the following page.
This page focuses on Cognito Sync.
Using Cognito Sync to share data between devices takes the form of storing and retrieving data against a data set.
Amazon Cognito lets you save end user data in datasets containing key-value pairs. This data is associated with an Amazon Cognito identity, so that it can be accessed across logins and devices.
Synchronizing data
In this case, we will prepare a dataset called “preference”, manage background color data with the key name “background-color”, and create a function to register and retrieve background color.
ID token acquisition
In this configuration, the OAuth flow is set to Implicit Grant.
With Implicit Grant, an ID token can be obtained from URL parameters.
const params = new URLSearchParams(location.hash.slice(1));
const idToken = params.get("id_token");
Code language: JavaScript (javascript)
For more details, please check the following page
Create Cognito Sync Client
Create a client object to access Cognito Sync.
import {
CognitoIdentityClient,
GetIdCommand
} from "@aws-sdk/client-cognito-identity";
import {
fromCognitoIdentityPool
} from "@aws-sdk/credential-provider-cognito-identity";
import {
CognitoSyncClient,
ListRecordsCommand,
UpdateRecordsCommand
} from "@aws-sdk/client-cognito-sync";
const cognitoIdentityClient = new CognitoIdentityClient({ region: REGION });
const cognitoSyncClient = new CognitoSyncClient({
region: REGION,
credentials: fromCognitoIdentityPool({
client: cognitoIdentityClient,
identityPoolId: IDENTITY_POOL_ID,
logins: {
[`cognito-idp.${REGION}.amazonaws.com/${USER_POOL_ID}`]: idToken
}
})
});
Code language: JavaScript (javascript)
Import the required classes and functions from the installed package.
Use them to create a Cognito Sync client.
Store values in Cosnigo Sync dataset
Access to Cognito Sync is broadly divided into storing and retrieving values.
First, let’s check the storage method.
const identityId = response.IdentityId;
const setBackgroundColorToCognitoSyncDataset = async (color) => {
const listRecordsResponse = await cognitoSyncClient.send(
new ListRecordsCommand({
DatasetName: DATASET,
IdentityId: identityId,
IdentityPoolId: IDENTITY_POOL_ID
})
);
const syncSessionToken = listRecordsResponse.SyncSessionToken;
const syncCount = (() => {
for (let record of listRecordsResponse.Records) {
if (record.Key == DATASET_KEY) {
return record.SyncCount + 1;
}
}
return 0;
})();
const response = await cognitoSyncClient.send(
new UpdateRecordsCommand({
DatasetName: DATASET,
IdentityId: identityId,
IdentityPoolId: IDENTITY_POOL_ID,
RecordPatches: [{
Key: DATASET_KEY,
Op: "replace",
SyncCount: syncCount,
Value: color
}],
SyncSessionToken: syncSessionToken
})
);
document.body.style.background = color;
};
window.setBackgroundColorToCognitoSyncDataset = setBackgroundColorToCognitoSyncDataset;
document.getElementById("button-set").addEventListener("click", function(event) {
var color = document.getElementById("background-color").value;
setBackgroundColorToCognitoSyncDataset(color);
});
Code language: JavaScript (javascript)
To store values in the Cognito Sync dataset using the AWS SDK for JavaScript v3, the following steps must be performed
- run ListRecordsCommand to get the dataset information and check the current SyncCount from the SyncSessionToken.
- execute UpdateRecordsCommand, specify the latest SyncCount, and then execute “replace”
To execute the above two commands, the Cognito ID is required, which is obtained by executing GetIdCommand.
ListRecordsCommand, which is executed to obtain the values of SyncSessionToken and SyncCount.
SyncCount is described in the API reference as follows
Last known server sync count for this record. Set to 0 if unknown.
RecordPatch
In other words, to store a value in the data set, it must be set to 0 the first time and incremented by the current value the second and subsequent times.
Among the parameters passed when executing UpdateRecordsCommand, RecordsPathes is the key point.
This parameter specifies the operation to be performed in addition to the value to be stored and the associated key. The operation is specified by the Op parameter.
An operation, either replace or remove.
RecordPatch
In this case, the objective is to update the value, so “replace” is specified to save the background color information.
The created function (setBackgroundColorToCognitoSyncDataset) is set as a global function.
In addition, set this function to be executed when the button for saving is pressed.
Retrieving values from Cognito Sync dataset
Then check the acquisition method.
const getBackgroundColorFromCognitoSyncDataset = async () => {
const listRecordsResponse = await cognitoSyncClient.send(
new ListRecordsCommand({
DatasetName: DATASET,
IdentityId: identityId,
IdentityPoolId: IDENTITY_POOL_ID
})
);
for (let record of listRecordsResponse.Records) {
if (record.Key == DATASET_KEY) {
document.body.style.background = record.Value;
break;
}
}
};
window.getBackgroundColorFromCognitoSyncDataset = getBackgroundColorFromCognitoSyncDataset;
document.getElementById('button-get').addEventListener('click', function(event) {
getBackgroundColorFromCognitoSyncDataset();
});
Code language: JavaScript (javascript)
To retrieve values from the Cognito Sync dataset using AWS SDK for JavaScript v3, execute the ListRecordsCommand.
From the retrieved records, check the keys and get the background color information.
This function (getBackgroundColorFromCognitoSyncDataset) is also set up as a global function.
This function is set to be executed when the button for acquisition is pressed.
S3 Static Website Hosting
The static website hosting feature publishes HTML files placed in S3 buckets.
Please see the following page for details.
Architecture
We will use CloudFormation to build this environment and check its actual behavior.
Create CloudFormation stacks and check resources in stacks
Create a CloudFormation stack.
For more information on how to create stacks and check each stack, please refer to the following page.
After checking the resources for each stack, the following is the information for the main resources created this time.
- Name of the S3 bucket: dva-03-001
- Cognito user pool ID: ap-northeast-1_LCLoZND22
- Cognito user pool app client ID: 2al2uf1i5bs4g9rc6ruu702mbu
- Cognito user pool domain prefix: dva-03-001
- Cognito ID pool ID: ap-northeast-1:800ca6c3-73fb-4c6f-ae5e-e0a91e7fb994
Place HTMLs in S3 bucket
Place the HTML in the S3 bucket and prepare the contents after sign-in/sign-out.
Access Cognito Sync: 1st device (browser)
Now that we are ready, let’s actually access the hosted UI.
First, launch your browser (Chrome) and access the following URL.
https://s3-ap-northeast-1.amazonaws.com/dva-03-001/index.html
Click “Sign In” to go to the sign-in page.
The sign-up process is required only for the first time. For more information about the signup process, please refer to Create sign-in page in the Cognito user pool – Accessing the hosted UI: Sign up. This time, we will register a user name of “awstut”.
After signing in, you will see a page like the one below.
Enter a background color in the right frame of background-color and press “set background-color”.
The background color has been changed successfully.
In addition to changing the background color, JavaScript saved “red” to the Cognito Sync data set.
Access Cognito Sync: 2nd device (browser)
Now, launch a different browser (Safari).
After signing in, access the above page.
Press “get background-color” to get the background color you have just set.
The background color has changed.
After accessing the Cognito Sync dataset and retrieving the data, I was able to change the background color successfully.
The above operation will register a new Identity ID in the ID pool.
Looking at more details, we can also see that a data set called preference has been created.
The dataset is registered with “background-color” as the key and “red” as the value.
By linking the user pool and identity pool in this way, Cognito Sync can be used.
Summary
We have confirmed that we can share data between devices by accessing the Cognito Sync dataset.