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

时间:2014-10-10 18:43:15

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

我正在使用移动后端启动器,我正在尝试在使用secure 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)声明

  

在下面的代码中,后端允许在“由客户端担保”中进行呼叫   ID“模式。它还设置了createdBy / updatedBy / owner属性   CloudEntity自动

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和所有者属性?

1 个答案:

答案 0 :(得分:1)

我在使用移动后端启动源时遇到了类似的问题。即使我按照此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行并重新部署您的后端。这样做会使您的应用的所有用户都能够对相关实体进行更新。这可能会有风险如果您严格关注所有权。所以,在采用这种方法之前,请考虑您的安全问题.Haven完成了,您现在可以自由更新相关的云实体。记住在服务器端默认新部署的后端。