私はこれとこのチュートリアルに従おうとしましたが、これがどのように行われるべきかはわかりません. CognitoSyncを使用していますが、同期サービスを開始しようとすると、 「Identity_id と dataset_name が一意ではありません」という例外に直面しています。
Amazon コンソールで IdentityPool を作成し、サーバー サイド クラスのパッケージ名、つまり「com.leversystems.devauth」を DeveloperProvider として指定し、これをサーバー クラスと Android アプリケーションで使用しました。サーバークラスで
map.put("com.leversystems.devauth", "someUniqueId");
Android アプリで
logins.put("com.leversystems.devauth", cognitoProvider.getToken());
これが私のコードです
Java サーバー側
package com.leversystems.devauth;
import java.util.HashMap;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.cognitoidentity.AmazonCognitoIdentityClient;
import com.amazonaws.services.cognitoidentity.model.GetOpenIdTokenForDeveloperIdentityRequest;
import com.amazonaws.services.cognitoidentity.model.GetOpenIdTokenForDeveloperIdentityResult;
public class DevAuth {
private BasicAWSCredentials credentials = null;
private String myAwsAccessKey = "myaccesskey";
private String myAwsSecretKey = "mysecretkey";
private String identityPoolID = "identityPoolid";
private String authARN = "arn:aws:iam::782936514542:role/DefaultRole";
private String identityId;
private String token;
public DevAuth()
{
identityId = "No id has been set yet!";
token = "No token has been set yet!";
initializeSecurity();
}
public String getToken()
{
return this.token;
}
public String getIdentityId()
{
return this.identityId;
}
public void initializeSecurity(){
credentials = new BasicAWSCredentials(myAwsAccessKey , myAwsSecretKey);
AmazonCognitoIdentityClient client =
new AmazonCognitoIdentityClient(credentials);
GetOpenIdTokenForDeveloperIdentityRequest tokenRequest =
new GetOpenIdTokenForDeveloperIdentityRequest();
tokenRequest.setIdentityPoolId(identityPoolID);
HashMap<String, String> map = new HashMap<String, String>();
map.put("com.leversystems.devauth", "nameid.number@provider.com");
//Duration of the generated OpenID Connect Token
tokenRequest.setLogins(map);
tokenRequest.setTokenDuration(1000l);
GetOpenIdTokenForDeveloperIdentityResult result
= client.getOpenIdTokenForDeveloperIdentity(tokenRequest);
this.identityId = result.getIdentityId();
this.token = result.getToken();
}}
このクラスの Web サービスを作成し、別のクラスBridge クラスでこの関数を呼び出して、トークンと ID を Android アプリケーションに送信します。これは正常に機能しています。Android アプリケーションで Token と IdentityId を取得しています。
Android クラス
MainActivity クラス
package com.leversystems.authserver;
import java.util.HashMap;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.os.StrictMode;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.amazonaws.auth.AWSCognitoIdentityProvider;
import com.amazonaws.auth.CognitoCachingCredentialsProvider;
import com.amazonaws.mobileconnectors.cognito.CognitoSyncManager;
import com.amazonaws.mobileconnectors.cognito.Dataset;
import com.amazonaws.mobileconnectors.cognito.Dataset.SyncCallback;
import com.amazonaws.mobileconnectors.cognito.Record;
import com.amazonaws.mobileconnectors.cognito.SyncConflict;
import com.amazonaws.mobileconnectors.cognito.exceptions.DataStorageException;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.cognitoidentity.AmazonCognitoIdentity;
import com.amazonaws.services.cognitoidentity.model.GetOpenIdTokenForDeveloperIdentityRequest;
import com.amazonaws.services.cognitoidentity.model.GetOpenIdTokenForDeveloperIdentityResult;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
public class MainActivity extends Activity {
AWSCognitoIdentityProvider cognitoProvider;
CognitoCachingCredentialsProvider credentialsProvider;
AmazonCognitoIdentity identityClient;
GetOpenIdTokenForDeveloperIdentityRequest idRequest;
GetOpenIdTokenForDeveloperIdentityResult idResp;
CognitoSyncManager client;
Dataset dataset;
TextView tv1;
TextView tv2;
TextView tv3;
Button btn1;
Button btn2;
final String ACC_ID = "myAccountID";
final String IDENTITY_POOL_ID = "identityPoolId";
final String AUTHORIZATION_ARN = "DefaultRole";
final String ACCESS_KEY = "myAccessKey";
final String SECRET_KEY = "mySecretKey";
Credentials cred;
public class Credentials {
String identityId;
String token;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
playerName = (TextView) findViewById(R.id.textView1);
currentLevel = (TextView) findViewById(R.id.textView2);
highScore = (TextView) findViewById(R.id.textView3);
btn1 = (Button) findViewById(R.id.button1);
btn2 = (Button) findViewById(R.id.button2);
btn3 = (Button) findViewById(R.id.button3);
initCognito();
btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
displayCogntioSyncData();
}
});
btn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
addCognitoSyncData();
}
});
btn3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
wipeCognitoSyncData();
}
});
}
private void initCognito() {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);
AsyncHttpClient client = new AsyncHttpClient();
client.get(
"http://192.168.1.112:8080/AuthenticationService/services/auth/gctbda",
new AsyncHttpResponseHandler() {
// When the response returned by REST has Http response code
// '200'
@Override
public void onSuccess(String response) {
try {
Gson gson = new Gson();
JsonParser jsonParser = new JsonParser();
JsonArray resultArray = jsonParser.parse(response)
.getAsJsonArray();
for (JsonElement credProvider : resultArray) {
cred = gson.fromJson(credProvider,
Credentials.class);
BYOIProvider.identityId = cred.identityId;
BYOIProvider.token = cred.token;
System.out.println("Id: " + cred.identityId);
System.out.println("Token: " + cred.token);
}
syncCognito();
} catch (Exception e) {
System.err.println("Exception in OnSuccess: "
+ e.getMessage());
}
}
});
}
private void syncCognito() {
cognitoProvider = new BYOIProvider(ACC_ID, IDENTITY_POOL_ID);
credentialsProvider = new CognitoCachingCredentialsProvider(
getApplicationContext(), cognitoProvider, null,
AUTHORIZATION_ARN);
cognitoProvider.refresh();
HashMap<String, String> logins = new HashMap<String, String>();
logins.put("com.leversystems.devauth", cognitoProvider.getToken());
credentialsProvider.setLogins(logins);
credentialsProvider.refresh();
client = new CognitoSyncManager(getApplicationContext(),
IDENTITY_POOL_ID, Regions.US_EAST_1, credentialsProvider);
dataset = client.openOrCreateDataset("GameInfo");
synchronize();
}
private void wipeCognitoSyncData() {
client.wipeData();
dataset.delete();
synchronize();
}
private void addCognitoSyncData() {
dataset.put("playerName", "Muneeb");
dataset.put("currentLevel", "29");
dataset.put("highScore", "120345");
synchronize();
}
private void displayCogntioSyncData() {
synchronize();
playerName.setText(dataset.get("playerName"));
currentLevel.setText(dataset.get("currentLevel"));
highScore.setText(dataset.get("highScore"));
}
private void synchronize() {
dataset.synchronize(new SyncCallback() {
@Override
public boolean onConflict(Dataset arg0, List<SyncConflict> arg1) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean onDatasetDeleted(Dataset arg0, String arg1) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean onDatasetsMerged(Dataset arg0, List<String> arg1) {
// TODO Auto-generated method stub
return false;
}
@Override
public void onFailure(DataStorageException arg0) {
System.err.println("Error onSyncro: " + arg0.getMessage());
}
@Override
public void onSuccess(Dataset arg0, List<Record> arg1) {
System.out.println("Dataset Synchronized!");
}
});
}
}
BYOIProvider クラス
package com.leversystems.authserver;
import com.amazonaws.auth.AWSAbstractCognitoIdentityProvider;
public class BYOIProvider extends AWSAbstractCognitoIdentityProvider {
public static String id;
public static String token;
public BYOIProvider(String acctId, String identityPoolId) {
super(acctId, identityPoolId);
}
@Override
public String getProviderName() {
return "com.leversystems.devauth";
}
@Override
public String refresh() {
update(id, token);
return null;
}
}
ワークフロー
- ボタンがクリックされると Android アプリからgetCredentials()が呼び出され、Java サーバー クラスからトークンと ID が取得されます。
- その後、トークンと ID がBYOIProvider クラスに渡されて更新されます。
- syncData()が呼び出され、CognitoCredentialProvider および BYOIProvider 変数が初期化されます。
- CognitoSyncManager は、CognitoCredentialProvider のオブジェクトで初期化されます。
- この後、例外エラーが発生します
列 identity_id と dataset_name が一意ではありません
このコード行で
データセット = client.openOrCreateDataset("MyData");
更新-1 (2014 年 11 月 11 日)
OK、refresh() の戻り文字列をトークン変数に変更しました。これがスタック トレースです。
11-11 12:58:52.196: I/View(29237): Touch down dispatch to android.widget.Button{4186d880 VFED..C. ........ 206,342-417,438 #7f080003 app:id/button1}, event = MotionEvent { action=ACTION_DOWN, id[0]=0, x[0]=76.0, y[0]=34.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=228482273, downTime=228482273, deviceId=2, source=0x1002 }
11-11 12:58:52.213: D/GraphicBuffer(29237): create handle(0x5ed83e60) (w:720, h:1280, f:1)
11-11 12:58:52.222: I/SurfaceTextureClient(29237): [STC::queueBuffer] (this:0x5d12eb78) fps:0.10, dur:20282.80, max:20162.90, min:119.90
11-11 12:58:52.222: I/SurfaceTextureClient(29237): [STC::queueBuffer] this:0x5d12eb78, api:1, last queue time elapsed:20162.90
11-11 12:58:52.326: I/View(29237): Touch up dispatch to android.widget.Button{4186d880 VFED..C. ...P.... 206,342-417,438 #7f080003 app:id/button1}, event = MotionEvent { action=ACTION_UP, id[0]=0, x[0]=76.0, y[0]=34.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=228482404, downTime=228482273, deviceId=2, source=0x1002 }
11-11 12:58:52.327: V/Provider/Settings(29237): from settings cache , name = sound_effects_enabled , value = 0
11-11 12:58:52.328: D/dalvikvm(29237): create interp thread : stack size=128KB
11-11 12:58:52.328: D/dalvikvm(29237): create new thread
11-11 12:58:52.328: D/dalvikvm(29237): new thread created
11-11 12:58:52.328: D/dalvikvm(29237): update thread list
11-11 12:58:52.329: D/dalvikvm(29237): threadid=15: interp stack at 0x60115000
11-11 12:58:52.329: D/dalvikvm(29237): threadid=15: created from interp
11-11 12:58:52.329: D/dalvikvm(29237): start new thread
11-11 12:58:52.329: D/dalvikvm(29237): threadid=15: notify debugger
11-11 12:58:52.329: D/dalvikvm(29237): threadid=15 (RefQueueWorker@org.apache.http.impl.conn.tsccm.ConnPoolByRoute@419852e8): calling run()
11-11 12:58:52.330: I/System.out(29237): httpget:http://192.168.1.112:8080/AuthenticationService/services/auth/gctbda
11-11 12:58:52.331: I/System.out(29237): http://192.168.1.112:8080/AuthenticationService/services/auth/gctbda
11-11 12:58:52.331: D/dalvikvm(29237): create interp thread : stack size=128KB
11-11 12:58:52.331: D/dalvikvm(29237): create new thread
11-11 12:58:52.332: D/dalvikvm(29237): new thread created
11-11 12:58:52.332: D/dalvikvm(29237): update thread list
11-11 12:58:52.332: D/dalvikvm(29237): threadid=16: interp stack at 0x60235000
11-11 12:58:52.332: D/dalvikvm(29237): threadid=16: created from interp
11-11 12:58:52.332: D/dalvikvm(29237): start new thread
11-11 12:58:52.333: D/dalvikvm(29237): threadid=16: notify debugger
11-11 12:58:52.333: D/dalvikvm(29237): threadid=16 (pool-3-thread-1): calling run()
11-11 12:58:52.336: I/System.out(29237): [socket][1] connection /192.168.1.112:8080;LocalPort=35830(10000)
11-11 12:58:52.336: I/System.out(29237): [CDS]connect[/192.168.1.112:8080] tm:10
11-11 12:58:52.336: D/Posix(29237): [Posix_connect Debug]Process com.leversystems.authserver :8080
11-11 12:58:52.358: I/System.out(29237): [socket][/192.168.1.136:35830] connected
11-11 12:58:52.358: I/System.out(29237): [CDS]rx timeout:10000
11-11 12:58:52.358: I/System.out(29237): [CDS]SO_SND_TIMEOUT:0
11-11 12:58:52.360: I/System.out(29237): >doSendRequest
11-11 12:58:52.361: I/System.out(29237): <doSendRequest
11-11 12:58:53.259: I/AmazonWebServiceClient(29237): {cognito-sync, us-east-1} was not found in region metadata, trying to construct an endpoint using the standard pattern for this region: 'cognito-sync.us-east-1.amazonaws.com'.
11-11 12:58:53.259: D/CognitoCachingCredentialsProvider(29237): Identity id is changed
11-11 12:58:53.259: D/CognitoCachingCredentialsProvider(29237): Saving identity id to SharedPreferences
11-11 12:58:53.260: I/CognitoSyncManager(29237): identity change detected
11-11 12:58:53.271: W/System.err(29237): Exception in OnSuccess: columns identity_id, dataset_name are not unique (code 19)
アップデート 2 (2014 年 11 月 13 日)
追加する
credentialsProvider.refresh();
setLogins()/withLogins() の後
間違ったトークンを試すと、それぞれの例外が発生します。私が提供しているトークンが正しい場合、この例外が発生します
Exception in onSuccess: Not authorized to perform sts:AssumeRoleWithWebIdentity (Service: AWSSecurityTokenService; Status Code: 403; Error Code: AccessDenied; Request ID: *SomeID*)
更新-3 (2014 年 11 月 13 日)
わかりましたので、IAM コンソールで新しいロールを作成しました。Update-2の例外が明確になりました。次の問題は最初の問題と同じです。AsyncHttpClient内で受け取っている正確な例外は
11-13 15:40:41.738: I/AmazonWebServiceClient(23921): {cognito-sync, us-east-1} was not found in region metadata, trying to construct an endpoint using the standard pattern for this region: 'cognito-sync.us-east-1.amazonaws.com'.
11-13 15:40:41.739: D/CognitoCachingCredentialsProvider(23921): Identity id is changed
11-13 15:40:41.739: D/CognitoCachingCredentialsProvider(23921): Saving identity id to SharedPreferences
11-13 15:40:41.740: I/CognitoSyncManager(23921): identity change detected
11-13 15:40:41.749: W/System.err(23921): Exception in OnSuccess: columns identity_id, dataset_name are not unique (code 19)
更新-4 (2014 年 11 月 14 日)
更新されたコードと StackTrace
コード:
credentialsProvider = new CognitoCachingCredentialsProvider(
getApplicationContext(), cognitoProvider, null,
AUTHORIZATION_ARN);
cognitoProvider.refresh();
スタックトレース:
11-14 11:25:01.357: I/AmazonWebServiceClient(31084): {cognito-sync, us-east-1} was not found in region metadata, trying to construct an endpoint using the standard pattern for this region: 'cognito-sync.us-east-1.amazonaws.com'.
11-14 11:25:01.358: D/CognitoCachingCredentialsProvider(31084): Identity id is changed
11-14 11:25:01.358: D/CognitoCachingCredentialsProvider(31084): Saving identity id to SharedPreferences
11-14 11:25:01.358: I/CognitoSyncManager(31084): identity change detected
11-14 11:25:01.367: W/System.err(31084): Exception in OnSuccess: columns identity_id, dataset_name, key are not unique (code 19)