且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

手机后台启动subscribeToCloudMessage将无法正常工作

更新时间:2023-01-26 12:47:35

此错误信息意味着物业 SubscriptionIDs (你可以找到它在 _DeviceSubscription 类在数据存储),价值超过500统一code字符限制。读文档供参考。

从文档:

  

有关文本字符串和unen codeD二进制数据(字节串),该   数据存储支持两种值类型:

     
      
  1. 在短字符串(最多500个统一code字符或字节)的索引   并可以在查询过滤器的条件和排序顺序被使用。
  2.   
  3. Longstrings(高达1兆字节)未编入索引,并可在查询过滤器不能使用,排序顺序。
  4.   

这样做的原因发生的是MBS试图写的所有预订到一个属性。

因此​​,要解决这个问题,我们需要使用文本,而不是字符串输入的 MBS后端源$ C ​​$ C SubscriptionIDs 属性。要做到这一点,你需要做以下的类变化 DeviceSubscription.java:

要设置文本属性替换该行code:

  deviceSubscription.setProperty(PROPERTY_SUBSCRIPTION_IDS,this.gson.toJson(订阅));
 

这一行:

  deviceSubscription.setProperty(PROPERTY_SUBSCRIPTION_IDS,新文本(this.gson.toJson(订阅)));
 

要获得文本从数据存储属性:

  1. 替换该行:

     字符串subscriptionString =(字符串)deviceSubscription.getProperty(PROPERTY_SUBSCRIPTION_IDS);
     

    这一点:

     文本文本=(文本)deviceSubscription.getProperty(PROPERTY_SUBSCRIPTION_IDS);
        串subscriptionString = text.getValue();
     

  2. 替换该行:

     字符串ID =(字符串)deviceSubscription.getProperty(PROPERTY_SUBSCRIPTION_IDS);
     

    这一点:

     文本文本=(文本)deviceSubscription.getProperty(PROPERTY_SUBSCRIPTION_IDS);
          字符串ID = text.getValue();
     

  3. 替换该行:

     的String [] IDS =新GSON()。fromJson((字符串)entity.getProperty(PROPERTY_SUBSCRIPTION_IDS)
                的String []类)。
     

    这一点:

     文本文本=(文本)entity.getProperty(PROPERTY_SUBSCRIPTION_IDS);
            。的String [] IDS =新GSON()fromJson(text.getValue()的String []类。);
     

似乎是有效的解决办法。我还没有发现负面影响我的项目至今。

注意:作为文档说明文本没有索引,可以在查询过滤器不能使用,排序顺序。因此,这种限制可能会导致另一个问题,如果物业 SubscriptionIDs 要求进行索引。

When I use the subscribeToCloudMessage() function with CloudBackendMessaging.TOPIC_ID_BROADCAST as the topicId as is done in CloudBackendFragment.java everything works fine but when I give this function my own string I get this message:

error:

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)

This error message means that property SubscriptionIDs (you can find it under the _DeviceSubscription Kind in your datastore) value exceeds 500 Unicode characters limit. Read docs for the reference.

From the docs:

For text strings and unencoded binary data (byte strings), the Datastore supports two value types:

  1. Short strings (up to 500 Unicode characters or bytes) are indexed and can be used in query filter conditions and sort orders.
  2. Longstrings (up to 1 megabyte) are not indexed and cannot be used in query filters and sort orders.

The reason for this happening is that MBS trying to write all subscriptions into one property.

So to overcome this issue we need to use Text instead of String type in MBS backend source code for the SubscriptionIDs property. To do so you need to make following changes in DeviceSubscription.java class:

To set Text property replace this line of code:

deviceSubscription.setProperty(PROPERTY_SUBSCRIPTION_IDS, this.gson.toJson(subscriptions));

with this line:

deviceSubscription.setProperty(PROPERTY_SUBSCRIPTION_IDS, new Text(this.gson.toJson(subscriptions)));

To get Text property from the datastore:

  1. Replace this line:

    String subscriptionString = (String) deviceSubscription.getProperty(PROPERTY_SUBSCRIPTION_IDS);
    

    with this:

    Text text = (Text) deviceSubscription.getProperty(PROPERTY_SUBSCRIPTION_IDS);
        String subscriptionString = text.getValue();
    

  2. Replace this line:

    String ids = (String) deviceSubscription.getProperty(PROPERTY_SUBSCRIPTION_IDS);
    

    with this:

    Text text = (Text) deviceSubscription.getProperty(PROPERTY_SUBSCRIPTION_IDS);
          String ids = text.getValue();
    

  3. Replace this line:

    String[] ids = new Gson().fromJson((String) entity.getProperty(PROPERTY_SUBSCRIPTION_IDS),
                String[].class);
    

    with this:

    Text text = (Text) entity.getProperty(PROPERTY_SUBSCRIPTION_IDS);
            String[] ids = new Gson().fromJson(text.getValue(), String[].class);
    

Seems to be valid solution. I have not noticed negative influence on my project so far.

NOTE: As docs stated Text is not indexed and cannot be used in query filters and sort orders. So this limitation could have cause another issues if the property SubscriptionIDs required to be indexed.