Java 移动后端启动器subscribeToCloudMessage将无法工作
当我将subscribeToCloudMessage()函数与CloudBackendMessaging.TOPIC_ID_BROADCAST一起用作topicId时,就像在CloudBackendFragment.java中一样,一切正常,但当我将自己的字符串赋予此函数时,我得到了以下消息: 错误:Java 移动后端启动器subscribeToCloudMessage将无法工作,java,android,json,google-maps,google-app-engine,Java,Android,Json,Google Maps,Google App Engine,当我将subscribeToCloudMessage()函数与CloudBackendMessaging.TOPIC_ID_BROADCAST一起用作topicId时,就像在CloudBackendFragment.java中一样,一切正常,但当我将自己的字符串赋予此函数时,我得到了以下消息: 错误: m.google.api.client.googleapis.json.GoogleJsonResponseException: 400 Bad Request "code": 400, "er
m.google.api.client.googleapis.json.GoogleJsonResponseException: 400 Bad Request
"code": 400,
"errors": [
{
"domain": "global",
"message": "SubscriptionIDs: String properties must be 500 characters or less. Instead, use com.google.appengine.api.datastore.Text, which can store strings of any length.",
"reason": "badRequest"
}
],
"message": "SubscriptionIDs: String properties must be 500 characters or less. Instead, use com.google.appengine.api.datastore.Text, which can store strings of any length."
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:111)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:38)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:312)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1042)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:410)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:343)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:460)
at com.google.cloud.backend.core.CloudBackend.list(CloudBackend.java:314)
at com.google.cloud.backend.core.CloudBackendAsync.access$8(CloudBackendAsync.java:1)
at com.google.cloud.backend.core.CloudBackendAsync$9.callBackend(CloudBackendAsync.java:270)
at com.google.cloud.backend.core.CloudBackendAsync$9.callBackend(CloudBackendAsync.java:1)
at com.google.cloud.backend.core.CloudBackendAsync$BackendCaller.run(CloudBackendAsync.java:402)
此错误消息表示属性
subscriptionId
(您可以在数据存储中的\u DeviceSubscription
类下找到)值超过了500个Unicode字符的限制。阅读以供参考
从文档中:
对于文本字符串和未编码的二进制数据(字节字符串)
数据存储支持两种值类型:
Text
而不是String
为SubscriptionIDs
属性键入。为此,您需要在DeviceSubscription.java
class中进行以下更改:
要设置Text
属性,请替换此行代码:
deviceSubscription.setProperty(PROPERTY_SUBSCRIPTION_IDS, this.gson.toJson(subscriptions));
这一行:
deviceSubscription.setProperty(PROPERTY_SUBSCRIPTION_IDS, new Text(this.gson.toJson(subscriptions)));
String subscriptionString = (String) deviceSubscription.getProperty(PROPERTY_SUBSCRIPTION_IDS);
String ids = (String) deviceSubscription.getProperty(PROPERTY_SUBSCRIPTION_IDS);
String[] ids = new Gson().fromJson((String) entity.getProperty(PROPERTY_SUBSCRIPTION_IDS),
String[].class);
要从数据存储中获取Text
属性,请执行以下操作:
deviceSubscription.setProperty(PROPERTY_SUBSCRIPTION_IDS, new Text(this.gson.toJson(subscriptions)));
String subscriptionString = (String) deviceSubscription.getProperty(PROPERTY_SUBSCRIPTION_IDS);
String ids = (String) deviceSubscription.getProperty(PROPERTY_SUBSCRIPTION_IDS);
String[] ids = new Gson().fromJson((String) entity.getProperty(PROPERTY_SUBSCRIPTION_IDS),
String[].class);
为此:
Text text = (Text) deviceSubscription.getProperty(PROPERTY_SUBSCRIPTION_IDS);
String subscriptionString = text.getValue();
Text text = (Text) deviceSubscription.getProperty(PROPERTY_SUBSCRIPTION_IDS);
String ids = text.getValue();
Text text = (Text) entity.getProperty(PROPERTY_SUBSCRIPTION_IDS);
String[] ids = new Gson().fromJson(text.getValue(), String[].class);
deviceSubscription.setProperty(PROPERTY_SUBSCRIPTION_IDS, new Text(this.gson.toJson(subscriptions)));
String subscriptionString = (String) deviceSubscription.getProperty(PROPERTY_SUBSCRIPTION_IDS);
String ids = (String) deviceSubscription.getProperty(PROPERTY_SUBSCRIPTION_IDS);
String[] ids = new Gson().fromJson((String) entity.getProperty(PROPERTY_SUBSCRIPTION_IDS),
String[].class);
为此:
Text text = (Text) deviceSubscription.getProperty(PROPERTY_SUBSCRIPTION_IDS);
String subscriptionString = text.getValue();
Text text = (Text) deviceSubscription.getProperty(PROPERTY_SUBSCRIPTION_IDS);
String ids = text.getValue();
Text text = (Text) entity.getProperty(PROPERTY_SUBSCRIPTION_IDS);
String[] ids = new Gson().fromJson(text.getValue(), String[].class);
deviceSubscription.setProperty(PROPERTY_SUBSCRIPTION_IDS, new Text(this.gson.toJson(subscriptions)));
String subscriptionString = (String) deviceSubscription.getProperty(PROPERTY_SUBSCRIPTION_IDS);
String ids = (String) deviceSubscription.getProperty(PROPERTY_SUBSCRIPTION_IDS);
String[] ids = new Gson().fromJson((String) entity.getProperty(PROPERTY_SUBSCRIPTION_IDS),
String[].class);
为此:
Text text = (Text) deviceSubscription.getProperty(PROPERTY_SUBSCRIPTION_IDS);
String subscriptionString = text.getValue();
Text text = (Text) deviceSubscription.getProperty(PROPERTY_SUBSCRIPTION_IDS);
String ids = text.getValue();
Text text = (Text) entity.getProperty(PROPERTY_SUBSCRIPTION_IDS);
String[] ids = new Gson().fromJson(text.getValue(), String[].class);
注意:如文档所述,
文本未编入索引,不能用于查询过滤器和排序顺序。因此,如果属性subscriptionID
需要编制索引,则此限制可能会导致另一个问题。似乎订阅ID是使用某些算法生成的,这些算法主要使用首次启动移动后端starter应用程序时获得的regid。为了解决这个问题,当我有它的时候,我只需要在给定的regid上调用substring并大大缩短它,但仍然保留足够长的时间来保证某种程度的唯一性
私有静态字符串doRegister(上下文){
字符串msg=“”;
试一试{
GoogleCloudMessaging gcm=GoogleCloudMessaging.getInstance(上下文);
字符串regId=gcm.register(常量项目编号)。子字符串(0,16);
msg=“设备已注册,注册ID=“+regId
此方法位于gcminentservice.java文件中。
请注意
.子串(0,16)
为我工作!我只是想和大家分享。@Juniper的答案在文档中是有意义的。
@jamrockRay的回答对我不起作用
但是我觉得这可能与作为Entitykind传递的字符串的值有关如果我将其更改回,则会出现错误。如果我将其更改回,则所有操作都会按预期进行,即使具有不同的实体属性。您可以确认吗?我转到cloud.google.com查询视图并删除了我的旧设备订阅ID,此后它工作正常。不确定您是否能够执行此操作。您可能是指D的服务器端代码java?有人能确认这是否有效吗?我想问题可能出在其他地方(见我的其他评论)。但如果不是,则应报告为错误。或者具有工作版本的用户应发送请求。@r-hold Yes您需要更改服务器端代码。这对我来说仍然有效。我猜这是一个错误。我看不出种类名称与此错误之间有任何关系。发生这种情况的原因是MBS正在尝试使用到一个属性。默认情况下,MBS仅使用一个GCM订阅,该订阅始终少于500个字符的限制。当多个SubscriptionID尝试写入一个属性时会发生错误。我猜您不仅更改了种类名称“Guestbook”但是你也修改了一些代码,添加了额外的订阅ID。例如Scope.FUTURE
和Scope.FUTURE\u和\u pass
,在你的查询中添加了更多的订阅。我明白你的观点,它也让我感到困惑。但我已经仔细检查了它。我正在使用fork中的示例,以及为Android Studio I准备的示例t已经使用“Scope.FUTURE\u和_pass”作为默认值。是的,我在某些地方修改了代码,但一旦我将entitykind名称改回“Guestbook”它又开始工作了。我会尽快尝试你的解决方案,只要我找到时间进行自定义部署。@Juniper我终于找到时间来实施你建议的错误并修复它们。我可以确认:它对我有效。仍然不明白为什么更改种类名称会把事情搞砸。@r-hold我和你有完全相同的问题,使用相同的后端启动器。如果我使用留言簿,它可以工作,如果我使用其他任何东西,我会得到相同的错误。我知道我在创建实体时没有做任何奇怪的事情,因为我使用完全相同的方法只是更改KindName。非常奇怪谢谢,结合Julien的修复,这对我有效。你尝试过更长的子字符串吗?正如我所见,这不应该工作到499吗?对于任何来这里寻找解决方案的人,请参阅本文。