View a markdown version of this page

實作推送同步 - 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 條件中的帳戶擔任執行此操作時的角色。

JSON
{ "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:遠端資料集的同步計數。您可以利用它來確定本機資料集已過期,而傳入的同步是新的。