使用移动后端启动程序从数据存储区发送和检索数据

时间:2013-08-09 15:26:37

标签: android google-cloud-datastore google-cloud-endpoints

我试图在我的Android应用程序中使用Mobile Backend Starter。为此,我需要在数据存储区中存储一些数据。 我使用提供的对象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的{​​{1}}中:

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); Date插入的数据会返回Calendar

null形式插入的数据会返回Integer

BigDecimal形式插入的数据会返回Long

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

1 个答案:

答案 0 :(得分:5)

经过一段时间的Android移动支持入门试验后,我发现了一个指向“非常有限”文档的链接:Mobile Backend Starter

我发现,如果您发送Integer(如果我信任文档FloatDouble),则会将其存储在 DataStore 作为数字字段。当您发送查询(通过BigDecimal)时,会以ClouldQuery的形式返回。

尽管如果您在Long中传递CloudEntity作为属性,它将作为String存储在 DataStore 中,并以此身份返回。这并非易事,因为String字段对允许的比较有限制。

如果您发送DateTime,文档会告诉您将返回String,但不会告诉您它将存储在 DataStore 中也是String

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

无论如何,每个DateTime默认CloudEntityDateTime都有两个CloudEntity.PROP_CREATED_AT个属性。您可以使用此字段设置查询过滤器。为此,您需要将过滤器设置为

CloudEntity.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)); 进行比较。如果你很勇敢,你可以使用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." ... (即1970-01-01T01:00:00.000 + 01:00)进行比较,因为后端收到了查询为:

dateTime = new DateTime(0)

不会发出任何错误,但不会返回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} 我尝试提交DOUBLE而不是Double,但它不起作用(没有错误,但没有结果)。

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

Integer

后端看到了:

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

我们将获得预期值(自1970-01-01T01:00:00.000 + 01:00以来所有实体都已更新)

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