android - cloudBackend.setCredential 未设置 CloudEntity 的 createdBy/updatedBy/owner 属性

标签 android google-app-engine google-cloud-datastore

我正在使用移动后端启动器,并且我正在尝试在使用 secured by id 设置时更新实体。我不断收到错误

com.google.api.client.googleapis.json.GoogleJsonResponseException: 401 Unauthorized
    {
    "code": 401,
    "errors": [
    {
    "domain": "global",
    "location": "Authorization",
    "locationType": "header",
    "message": "Insuffient permission for updating a CloudEntity: CE:123456 by: USER:123456",
    "reason": "required"
    }
    ],
    "message": "Insuffient permission for updating a CloudEntity: CE: 123456 by: USER:123456"
    }

文档 ( https://cloud.google.com/developers/articles/mobile-backend-starter-api-reference/#ciagaa ) 指出

In the code below, the backend allows the call in “Secured by Client ID” mode. It also sets createdBy/updatedBy/owner properties of CloudEntity automatically

GoogleAccountCredential credential =
  GoogleAccountCredential.usingAudience(this, "<Web Client ID>");
credential.setSelectedAccountName("<Google Account Name>");
cloudBackend.setCredential(credential);

所以我写了下面的代码

mCloudBackend = new CloudBackendMessaging(this);

GoogleAccountCredential credential = GoogleAccountCredential.usingAudience(this, Consts.AUTH_AUDIENCE);
    mCloudBackend.setCredential(credential);
    String accountName =
            mCloudBackend.getSharedPreferences().getString(
                    Consts.PREF_KEY_ACCOUNT_NAME, null);
    credential.setSelectedAccountName(accountName);
    mCloudBackend.setCredential(credential);
    newPost.setId(updateRide);
    mCloudBackend.update(newPost, handler);

不幸的是,这给出了上面的错误。但是,更新正在进行,因为我在查询数据存储时可以看到实体发生变化。问题似乎是因为 createdBy/updatedBy/owner 属性设置为 null,因此不会自动设置。

我看到其他问题的答案是在更新之前查询实体,使用它来设置上述属性,然后执行更新。我宁愿避免这种情况,因为它似乎是对数据存储的不必要调用。所以我的问题是如何获得 GoogleAccount createdBy updatedBy 和 owner 属性?

最佳答案

我在使用移动后端启动器源代码时遇到了类似的问题。尽管我遵循了此 link 中提供的答案,我无法解决问题。但是,我所做的是获取移动后端源代码并进行一些修改。获取代码并在 CrudOperations.java 文件中,您将看到这个方法

private Map<String, Entity> findAndUpdateExistingEntities(EntityListDto cdl, User user)
 throws UnauthorizedException{

// create a list of CEs with existing Id
EntityListDto entitiesWithIds = new EntityListDto();
Map<String, EntityDto> entitiesWithIdMap = new HashMap<String, EntityDto>();
for (EntityDto cd : cdl.getEntries()) {
  if (cd.getId() != null) {
    entitiesWithIds.add(cd);
    entitiesWithIdMap.put(cd.getId(), cd);
  }
}

// try to get existing CEs
Map<String, Entity> existingEntities = getAllEntitiesByKeyList(entitiesWithIds
    .readKeyList(user));

// update existing entities
for (String id : existingEntities.keySet()) {

  // check ACL
  Entity e = existingEntities.get(id);
  SecurityChecker.getInstance().checkAclForWrite(e, user);

  // update metadata
  EntityDto cd1 = entitiesWithIdMap.get(id);
  cd1.setUpdatedAt(new Date());
  if (user != null) {
    cd1.setUpdatedBy(user.getEmail());
  }

  // update the entity
  cd1.copyPropValuesToEntity(e);
}
return existingEntities;

在上面的代码中,注释掉SecurityChecker.getInstance().checkAclForWrite(e, user); throws UnAuthorizedException 行并重新部署您的后端。这样做将使您应用的所有用户都能够对相关实体进行更新。如果您严格关注所有权,这可能会有风险.因此,在采用这种方法之前请考虑您的安全问题。完成之后,您现在可以自由更新相关的云实体。请记住将服务器端新部署的后端设为默认设置。

关于android - cloudBackend.setCredential 未设置 CloudEntity 的 createdBy/updatedBy/owner 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26306006/

相关文章:

jquery - 使用 python、jQuery 和 AppEngine 对按钮单击响应进行重定向(使用 http post)

python - 如何使用 webapp2 的用户模型拥有用户名?

c# - Google Cloud Datastore 从 VB.net 进行仅键查询

java - 从java应用程序连接到谷歌数据存储

android - 我可以在itext 2.1.7中使用Playstore出售我的应用程序吗

android - 使用已安装的文件编辑器(如果有)编辑纯文本文件的 Intent

android - AppWidget 第一次添加时没有完成更新

python - OpenSSL s_client 和 Python SSL 模块在主机名证书上存在分歧

python - BadFilterError : invalid filter: Only one property per query may have inequality filters (<=, >=, <, >)

Android:如何以编程方式显示位置源设置?