Android Google云数据存储/移动后端启动器-更新/更新调用权限失败

Android Google云数据存储/移动后端启动器-更新/更新调用权限失败,android,google-app-engine,google-cloud-datastore,Android,Google App Engine,Google Cloud Datastore,使用Mobile Backend Starter(MBS)Android类(在Google开发控制台中创建新项目时作为示例项目分发,并在Google I/O 2013上演示),我能够通过调用CloudBackendMessaging.insertAll或.updateAll将新实体插入云数据存储。如果不存在实体,后者将创建实体,因此在功能上似乎与插入新记录相同 插入/创建工作正常。但是,当我尝试更新数据存储中的现有条目时,我收到了权限错误,例如(来自后端日志) 方法:mobilebackend.

使用Mobile Backend Starter(MBS)Android类(在Google开发控制台中创建新项目时作为示例项目分发,并在Google I/O 2013上演示),我能够通过调用CloudBackendMessaging.insertAll或.updateAll将新实体插入云数据存储。如果不存在实体,后者将创建实体,因此在功能上似乎与插入新记录相同

插入/创建工作正常。但是,当我尝试更新数据存储中的现有条目时,我收到了权限错误,例如(来自后端日志)

方法:mobilebackend.endpointV1.updateAll

错误代码:401

理由:必须

消息:更新CloudEntity:XXXXXX的权限不足:用户:YYYYYYY

这将导致logcat客户端出现匹配的访问错误

在所有情况下,我都在使用安全访问验证和有效的谷歌帐户(我自己的)

因此,插入的实体显示为“拥有”我的用户ID,“更新人”和“创建人”,显示我的谷歌帐户的电子邮件地址

但是,当更新现有记录时,使用完全相同的CloudBackendMessenger对象,因此使用相同的凭据等。后端告诉我,由于权限问题,无法更新。但如果我只是用相同的凭证创建实体,这肯定不正确吗?查看文档,我似乎应该能够在所有情况下编辑由相同用户ID拥有的实体(无论KindName是什么,也不管它是在[public]、[private]前面加上前缀还是什么都没有)


任何通过移动后端Starter for Datascore接收到更新权限错误的人都可以解释一下吗?今天的大部分时间我都在为这个问题绞尽脑汁。

在使用cloudBackendAsync.update(CloudEntity)时,我遇到了类似的错误“更新CloudEntity的权限不足”。我通过确保cloudEntity设置了createdAt字段来解决这个问题。createdAt是自动生成的,我想我不应该碰它。但这对我很管用。在我的例子中,我首先获得云实体的列表。这是当我得到云实体的createdAt字段时。然后,当我更新时,我会根据以前获得的实体设置createdAt字段。
编辑:也必须对所有者字段执行类似的操作。

与上面的一条评论类似,我在执行插入/更新/删除功能之前通过获取原始CloudEntity成功地解决了这个问题

    CloudQuery cq = new CloudQuery("datastoretype");
    cq.setLimit(1);
    cq.setFilter(Filter.eq("_id",id));

    cloudEntity.setId(id);
    mProcessingFragment.getCloudBackend().get(cloudEntity, handler);
此后,执行以下操作非常简单:

    mProcessingFragment.getCloudBackend().update(cloudEntity, handler);

无论是严格要求还是缺陷,文档都应该更清楚地说明这一点。

如果您不介意所有用户都能够访问您试图更新的实体,那么到目前为止发布的答案可以解决这个问题。然而,谷歌在此处详细介绍了保留访问权限的更好解决方案-

如果您想将用户的Google帐户信息传递到 每次调用时,使用CloudBackend#setCredential()方法(也可用 在子类上,CloudBackendAsync和CloudBackendMessaging)设置 调用任何移动后端之前的GoogleAccountCredential对象 方法

GoogleAccountCredential credential=GoogleAccountCredential.usingAudience(此“”);
凭证.setSelectedAccountName(“”);
cloudBackend.setCredential(凭证);
设置凭据使客户端能够在后端运行时进行操作 在“受客户端ID保护”模式下,并设置createdBy/updatedBy/owner CloudEntity的属性


这方面的一个解决方法似乎是查询,即通过list()调用获取要更新的CloudEntity,然后通过update()调用进行更新。不过,如果您可以直接对实体(通过其UID即setId()指定)执行更新,而无需先获取该实体,则会更好/更高效。您是否也尝试使用“事务”更新单个实体?@Franz Noel。这很有趣-请您详细说明如何在移动/客户端使用MBS与CloudEntity进行交易,这种方式可能需要代码片段?这很有趣-并可能解释为什么如果我“获取”,即列出记录,然后使用它进行更新,然后我就可以在没有权限问题的情况下执行更新了。我想知道是否有一种方法可以将createdAt字段设置为正确的值,而不首先实际获取记录(出于性能原因,我有很多更新要做)。您知道该字段是如何格式化/合成的吗?您可以从google开发控制台检查createdAt格式。进入你的应用控制台->云数据存储->查询->选择种类,你可以看到你的实体列表。好的,我来试一试。非常感谢这个提示,谁知道创建日期会给出一个权限错误呢?我也必须对所有者字段做同样的事情。实体已成功更新,但缺少所有者字段,该字段最初也是自动生成的。我正在尝试按照您的代码进行操作,但看不到您在更新中如何使用cloudquery。我在尝试你的过滤器时也会出错。那么,你能在这里发布你的完整代码吗?我似乎说得太快了,因为我试图自己实现它,并且遇到了问题-
GoogleAccountCredential credential = GoogleAccountCredential.usingAudience(this, "<Web Client ID>");
credential.setSelectedAccountName("<Google Account Name>");
cloudBackend.setCredential(credential);