3

我正在尝试在我的 Android 应用程序中使用 Mobile Backend Starter。为此,我需要在 Datastore 中存储一些数据。

我正在使用提供的对象CloudEntity,但我只能始终插入和读取String.

这是我用来发送数据的示例代码:

CloudEntity entity = new CloudEntity(TEST_KIND_NAME);

entity.put(KEY_DATE, new Date(System.currentTimeMillis()));
entity.put(KEY_CALENDAR, Calendar.getInstance());
entity.put(KEY_LONG,  Long.valueOf(Long.MAX_VALUE));                
entity.put(KEY_INTEGER, Integer.valueOf(Integer.MAX_VALUE));
getCloudBackend().insert(entity, simpleHandler);

这就是我读回数据的方式(下一个代码onComplete位于CloudBackendHandler

StringBuffer strBuff = new StringBuffer();
strBuff.append("Inserted: \n");
strBuff.append("\tId = " + result.getId() + "\n");
Object o;
o = result.get(KEY_DATE);            
strBuff.append("\tDate was retrieved as : " + ((o == null)? "null" : o.getClass().getName()) + "\n");
        
o = result.get(KEY_CALENDAR);
strBuff.append("\tCalendar was retrieved as : " + ((o == null)? "null" : o.getClass().getName()) + "\n");
        
o = result.get(KEY_LONG);
strBuff.append("\tLong was retrieved as : " + ((o == null)? "null" : o.getClass().getName()) + "\n");
        
o = result.get(KEY_INTEGER);
strBuff.append("\tInteger was retrieved as : " + ((o == null)? "null" : o.getClass().getName()) + "\n");
        
o = result.get(KEY_BOOLEAN);
strBuff.append("\tBoolean was retrieved as : " + ((o == null)? "null" : o.getClass().getName()) + "\n");
mTvInfo.setText(strBuff);

我得到的结果是:

插入DateCalendar返回的数据null

Integer作为返回插入的数据BigDecimal

插入的数据Long返回 a String

我的问题是:我可以发送(和读回)字符串以外的其他数据吗?如果是这样。如何?

4

1 回答 1

5

在对 Android Mobile Backed Starter 进行了一段时间的试验后,我发现了一个指向“某种”(非常有限的)文档的链接:Mobile Backend Starter

我发现,如果您发送一个Integer(并且如果我信任 de 文档 aFloat或 a ),它将作为数字字段Double存储在DataStore中。并且在您发送查询时返回(通过)。BigDecimalClouldQuery

不过,如果您将 aLong作为属性传递给CloudEntity,它将作为 a 存储StringDataStore中并按原样返回。这并非微不足道,因为String字段对允许的比较有限制。

如果您发送 a DateTime,文档会告诉您将返回 a String,但不会告诉您它也将作为 a存储在DataStoreString中。

这很重要,因为您无法与Strings 进行所有比较。只允许相等(和 ne)比较(您不能在查询中测试大于过滤器的String属性)。因此,您不能将时间戳存储为Long(将被转换为String并且您将无法比较它们),并且DateTime出于相同的原因您不能设置时间戳。而且您不能存储 Date 或 Calendar 对象。

无论如何,默认情况下每个CloudEntity都有两个属性和. 您可以使用此字段设置查询过滤器。为此,您需要将过滤器设置为DateTimeCloudEntity.PROP_CREATED_ATCloudEntity.PROP_UPDATED_AT

CloudQuery myQuery = new CloudQuery(<your kind name>);
myQuery.set<things>...
DateTime dateTime = new DateTime(<the time you want>);
myQuery.setFilter(F.gt(CloudEntity.PROP_UPDATED_AT, dateTime));

需要使用 a DateTime进行比较。如果您有兴趣,则不能使用Date代替来DateTime进行此比较。你会得到这个错误:

com.google.api.client.googleapis.json.GoogleJsonResponseException: 400 Bad Request
{
    "code": 400,
    "errors": [
    {
       "domain": "global",
       "message": "java.lang.IllegalArgumentException: _updatedAt:java.util.LinkedHashMap is not a supported property type.",
       "reason": "badRequest"
    }
    ],
    "message": "java.lang.IllegalArgumentException: _updatedAt: java.util.LinkedHashMap is not a supported property type."
...

其他奇怪的事情是,显然,您不能dateTime = new DateTime(0)(ie 1970-01-01T01:00:00.000+01:00) 进行比较,因为后端接收查询如下:

query: (_kindName:"Data") AND ( _updatedAt > "1970-01-01T01:00:00.000+01:00" ), schema: {_kindName=STRING, _updatedAt=STRING}

不会给出任何错误,但不会返回任何内容list: result: null。看起来它将比较视为String. 如果您DateTime dateTime = new DateTime(1)改用,您将发送一个查询:

list: executing query: {filterDto={operator=GT, values=[_updatedAt, 1970-01-01T01:00:00.001+01:00]},

看起来和以前一样,但后端将执行查询:

 query: (_kindName:"Data") AND ( _updatedAt > 1 ), schema: {_kindName=STRING, _updatedAt=DOUBLE}

正如我看到的 aDOUBLE我尝试提交 aDouble而不是 a DateTime,但它不起作用(没有错误但没有结果)。

但是,每个人都有好消息!我们可以用 Integeras 进行比较:

Integer anInteger = Integer.valueOf(0);
myQuery.setFilter(F.gt(CloudEntity.PROP_UPDATED_AT, anInteger));

后端看到:

query: (_kindName:"Data") AND ( _updatedAt > 0 ), schema: {_kindName=STRING, _updatedAt=INT32}

我们将得到期望值(自 1970-01-01T01:00:00.000+01:00 以来更新的所有实体)

抱歉我的错误(我的英语不好),我希望这可以帮助某人,至少可以节省他一些时间。

于 2013-08-18T13:43:06.050 回答