推播同步 - Amazon Cognito

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

推播同步

如果您第一次使用 Amazon Cognito Sync,請改用 AWS AppSync。像 Amazon Cognito Sync 一樣,AWS AppSync 是讓您在裝置間同步應用程式資料的服務。

可同步使用者資料,如應用程式偏好設定或遊戲狀態。也擴充這些功能,允許多個使用者在共用資料上即時同步及協作。

Amazon Cognito 會自動追蹤身分與裝置之間的關聯。使用推播同步功能可讓您確保在身分資料變更時,指定身分的每個執行個體都會收到通知。每當特定身分的同步存放區資料變更時,推播同步可確保與該身分相關聯的所有裝置都會收到靜音推送通知,通知他們有所變更。

注意

JavaScript、Unity 或 Xamarin 不支援推播同步。

您必須先設定帳戶來進行推播同步,並且在 Amazon Cognito 主控台中啟用推播同步,才能使用推播同步。

建立 Amazon Simple Notification Service (Amazon SNS) 應用程式

依照 SNS 開發人員指南中的說明,為您的支援平台建立並設定 Amazon SNS 應用程式。

在 Amazon Cognito 主控台中啟用推播同步

您可以透過 Amazon Cognito 主控台來啟用推播同步。從主控台首頁

  1. 針對要啟用推播同步的身分集區,按一下其名稱。該身分集區的 Dashboard (儀表板) 頁面隨即出現。

  2. Dashboard (儀表板) 頁面右上角,按一下 Manage Identity Pools (管理身分集區)。此時將出現 Federated Identities (聯合身分) 頁面。

  3. 向下捲動,然後按一下 Push synchronization (推播同步) 將其展開。

  4. Service role (服務角色) 下拉式選單中,選取授予 Cognito 許可的 IAM 角色來傳送 SNS 通知。按一下 Create role (建立角色),在 AWS IAM 主控台中建立或修改與身分集區相關聯的角色。

  5. 選取平台應用程式,然後按一下 Save Changes (儲存變更)

  6. 授予對應用程式的 SNS 存取權

在 AWS Identity and Access Management 主控台中,將您的 IAM 角色設定為擁有完整的 Amazon SNS 存取權,或建立擁有完整 Amazon SNS 存取權的新角色。下列範例角色信任政策授予 Amazon Cognito Sync 擔任 IAM 角色的有限功能。Amazon Cognito Sync 只能代表 aws:SourceArn 條件中的身分集區和 aws:SourceAccount 條件中的帳戶擔任執行此操作時的角色。

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "cognito-sync.amazonaws.com" }, "Action": "sts:AssumeRole", "Condition": { "StringEquals": { "AWS:SourceAccount": "123456789012" }, "ArnLike": { "AWS:SourceArn": "arn:aws:cognito-identity:us-east-1:123456789012:identitypool/us-east-1:177a950c-2c08-43f0-9983-28727EXAMPLE" } } } ] }

若要進一步了解 IAM 角色,請參閱角色 (委派和聯合)

在您的應用程式中使用播送同步:Android

您的應用程式將需要匯入 Google Play 服務。您可以從 Android SDK manager 下載最新版的 Google Play SDK。請遵循 Android 實作的 Android 說明文件來註冊您的應用程式,並從 GCM 接收註冊 ID。取得註冊 ID 之後,您必須向 Amazon Cognito 註冊裝置,如下列程式碼片段所示:

String registrationId = "MY_GCM_REGISTRATION_ID"; try { client.registerDevice("GCM", registrationId); } catch (RegistrationFailedException rfe) { Log.e(TAG, "Failed to register device for silent sync", rfe); } catch (AmazonClientException ace) { Log.e(TAG, "An unknown error caused registration for silent sync to fail", ace); }

您現在可以訂閱裝置,以從特定資料集接收更新:

Dataset trackedDataset = client.openOrCreateDataset("myDataset"); if (client.isDeviceRegistered()) { try { trackedDataset.subscribe(); } catch (SubscribeFailedException sfe) { Log.e(TAG, "Failed to subscribe to datasets", sfe); } catch (AmazonClientException ace) { Log.e(TAG, "An unknown error caused the subscription to fail", ace); } }

若要停止從資料集接收推播通知,只要呼叫 unsubscribe 方法即可。若要訂閱 CognitoSyncManager物件中的所有資料集 (或特定子集),請使用 subscribeAll()

if (client.isDeviceRegistered()) { try { client.subscribeAll(); } catch (SubscribeFailedException sfe) { Log.e(TAG, "Failed to subscribe to datasets", sfe); } catch (AmazonClientException ace) { Log.e(TAG, "An unknown error caused the subscription to fail", ace); } }

實作 Android BroadcastReceiver 物件時,您可以檢查修改資料集的最新版本,並決定您的應用程式是否需要再次同步:

@Override public void onReceive(Context context, Intent intent) { PushSyncUpdate update = client.getPushSyncUpdate(intent); // The update has the source (cognito-sync here), identityId of the // user, identityPoolId in question, the non-local sync count of the // data set and the name of the dataset. All are accessible through // relevant getters. String source = update.getSource(); String identityPoolId = update.getIdentityPoolId(); String identityId = update.getIdentityId(); String datasetName = update.getDatasetName; long syncCount = update.getSyncCount; Dataset dataset = client.openOrCreateDataset(datasetName); // need to access last sync count. If sync count is less or equal to // last sync count of the dataset, no sync is required. long lastSyncCount = dataset.getLastSyncCount(); if (lastSyncCount < syncCount) { dataset.synchronize(new SyncCallback() { // ... }); } }

推送通知酬載中有下列索引鍵可供使用:

  • source:cognito-sync。這可以用來做為通知之間的區分要素。

  • identityPoolId:身分集區 ID。這可以用於驗證或其他資訊,雖然從接收者的觀點而言,這並不完整。

  • identityId:集區中的身分 ID。

  • datasetName:已更新之資料集的名稱。這可以用來進行 openOrCreateDataset 呼叫。

  • syncCount:遠端資料集的同步計數。您可以利用它來確定本機資料集已過期,而傳入的同步是新的。

在您的應用程式中使用推播同步:iOS - Objective-C

若要取得應用程式的裝置權杖,請依照有關「註冊遠端通知」的 Apple 說明文件來操作。從 APN 收到 NSData 物件形式的裝置權杖之後,您需要使用同步用戶端的 registerDevice: 方法,向 Amazon Cognito 註冊裝置,如下所示:

AWSCognito *syncClient = [AWSCognito defaultCognito]; [[syncClient registerDevice: devToken] continueWithBlock:^id(AWSTask *task) { if(task.error){ NSLog(@"Unable to registerDevice: %@", task.error); } else { NSLog(@"Successfully registered device with id: %@", task.result); } return nil; } ];

在偵錯模式下,您的裝置會向 APN 沙盒註冊;在版本模式下,則是向 APN 註冊。若要從特定資料集接收更新,請使用 subscribe方法:

[[[syncClient openOrCreateDataset:@"MyDataset"] subscribe] continueWithBlock:^id(AWSTask *task) { if(task.error){ NSLog(@"Unable to subscribe to dataset: %@", task.error); } else { NSLog(@"Successfully subscribed to dataset: %@", task.result); } return nil; } ];

若要停止從資料集接收推播通知,只要呼叫 unsubscribe方法即可:

[[[syncClient openOrCreateDataset:@”MyDataset”] unsubscribe] continueWithBlock:^id(AWSTask *task) { if(task.error){ NSLog(@"Unable to unsubscribe from dataset: %@", task.error); } else { NSLog(@"Successfully unsubscribed from dataset: %@", task.result); } return nil; } ];

若要訂閱 AWSCognito物件中的所有資料集,請呼叫 subscribeAll

[[syncClient subscribeAll] continueWithBlock:^id(AWSTask *task) { if(task.error){ NSLog(@"Unable to subscribe to all datasets: %@", task.error); } else { NSLog(@"Successfully subscribed to all datasets: %@", task.result); } return nil; } ];

在呼叫 subscribeAll之前,請務必在每個資料集上至少同步一次,這樣資料集才會存在於伺服器上。

若要對推播通知做出反應,您需要在應用程式委派中實作 didReceiveRemoteNotification方法:

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { [[NSNotificationCenter defaultCenter] postNotificationName:@"CognitoPushNotification" object:userInfo]; }

如果您使用通知處理常式來發佈通知,就可以在應用程式中有您的資料集頭銜的其他地方回應通知。如果您訂閱通知,像這樣 ...

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceivePushSync:) name: :@"CognitoPushNotification" object:nil];

...您可以對通知採取像這樣的動作:

- (void)didReceivePushSync:(NSNotification*)notification { NSDictionary * data = [(NSDictionary *)[notification object] objectForKey:@"data"]; NSString * identityId = [data objectForKey:@"identityId"]; NSString * datasetName = [data objectForKey:@"datasetName"]; if([self.dataset.name isEqualToString:datasetName] && [self.identityId isEqualToString:identityId]){ [[self.dataset synchronize] continueWithBlock:^id(AWSTask *task) { if(!task.error){ NSLog(@"Successfully synced dataset"); } return nil; }]; } }

推送通知酬載中有下列索引鍵可供使用:

  • source:cognito-sync。這可以用來做為通知之間的區分要素。

  • identityPoolId:身分集區 ID。這可以用於驗證或其他資訊,雖然從接收者的觀點而言,這並不完整。

  • identityId:集區中的身分 ID。

  • datasetName:已更新之資料集的名稱。這可以用來進行 openOrCreateDataset呼叫。

  • syncCount:遠端資料集的同步計數。您可以利用它來確定本機資料集已過期,而傳入的同步是新的。

在您的應用程式中使用推播同步:iOS - Swift

若要取得應用程式的裝置權杖,請依照有關「註冊遠端通知」的 Apple 說明文件來操作。從 APN 收到 NSData 物件形式的裝置權杖之後,您需要使用同步用戶端的 registerDevice: 方法,向 Amazon Cognito 註冊裝置,如下所示:

let syncClient = AWSCognito.default() syncClient.registerDevice(devToken).continueWith(block: { (task: AWSTask!) -> AnyObject! in if (task.error != nil) { print("Unable to register device: " + task.error.localizedDescription) } else { print("Successfully registered device with id: \(task.result)") } return task })

在偵錯模式下,您的裝置會向 APN 沙盒註冊;在版本模式下,則是向 APN 註冊。若要從特定資料集接收更新,請使用 subscribe方法:

syncClient.openOrCreateDataset("MyDataset").subscribe().continueWith(block: { (task: AWSTask!) -> AnyObject! in if (task.error != nil) { print("Unable to subscribe to dataset: " + task.error.localizedDescription) } else { print("Successfully subscribed to dataset: \(task.result)") } return task })

若要停止從資料集接收推播通知,請呼叫 unsubscribe方法:

syncClient.openOrCreateDataset("MyDataset").unsubscribe().continueWith(block: { (task: AWSTask!) -> AnyObject! in if (task.error != nil) { print("Unable to unsubscribe to dataset: " + task.error.localizedDescription) } else { print("Successfully unsubscribed to dataset: \(task.result)") } return task })

若要訂閱 AWSCognito物件中的所有資料集,請呼叫 subscribeAll

syncClient.openOrCreateDataset("MyDataset").subscribeAll().continueWith(block: { (task: AWSTask!) -> AnyObject! in if (task.error != nil) { print("Unable to subscribe to all datasets: " + task.error.localizedDescription) } else { print("Successfully subscribed to all datasets: \(task.result)") } return task })

在呼叫 subscribeAll之前,請務必在每個資料集上至少同步一次,這樣資料集才會存在於伺服器上。

若要對推播通知做出反應,您需要在應用程式委派中實作 didReceiveRemoteNotification方法:

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) { NSNotificationCenter.defaultCenter().postNotificationName("CognitoPushNotification", object: userInfo) })

如果您使用通知處理常式來發佈通知,就可以在應用程式中有您的資料集頭銜的其他地方回應通知。如果您訂閱通知,像這樣 ...

NSNotificationCenter.defaultCenter().addObserver(observer:self, selector:"didReceivePushSync:", name:"CognitoPushNotification", object:nil)

...您可以對通知採取像這樣的動作:

func didReceivePushSync(notification: NSNotification) { if let data = (notification.object as! [String: AnyObject])["data"] as? [String: AnyObject] { let identityId = data["identityId"] as! String let datasetName = data["datasetName"] as! String if self.dataset.name == datasetName && self.identityId == identityId { dataset.synchronize().continueWithBlock {(task) -> AnyObject! in if task.error == nil { print("Successfully synced dataset") } return nil } } } }

推送通知酬載中有下列索引鍵可供使用:

  • source:cognito-sync。這可以用來做為通知之間的區分要素。

  • identityPoolId:身分集區 ID。這可以用於驗證或其他資訊,雖然從接收者的觀點而言,這並不完整。

  • identityId:集區中的身分 ID。

  • datasetName:已更新之資料集的名稱。這可以用來進行 openOrCreateDataset呼叫。

  • syncCount:遠端資料集的同步計數。您可以利用它來確定本機資料集已過期,而傳入的同步是新的。