firebase - 如何通过 REST 在 Firestore 文档中添加/删除数组元素?
问题描述
我想使用一个数组将来自 Arduino 的温度读数存储在 Firestore 数据库中。到目前为止,我(可能很糟糕)的思考方式是阅读文档,在 Arduino 上执行我的数组操作,然后将整个数组发送回 Firestore。我根本不知道如何通过 REST 写入 Firestore,所以我还没有实现它。这是我的代码:
void writeTemp(String url, int temperature) {
// writeTemp() appends the given temperature to an array. temperature[0]
// holds the oldest temperature while temperature[9] holds the first.
// When a new temperature is put in, the last one is taken out.
HTTPClient http;
http.begin(url);
int httpCode = http.GET();
// Gets the current temperature array from the provided URL.
String payload = http.getString();
Serial.println(httpCode); // Prints HTTP response code.
// Calculates the size of the JSON buffer. This is big enough for 11
// temperature values that are all 3 digits so as long as you're not using
// this on the Sun you're probably fine.
const size_t capacity = JSON_ARRAY_SIZE(11) + 14 * JSON_OBJECT_SIZE(1) +
JSON_OBJECT_SIZE(4) + 440;
DynamicJsonDocument doc(capacity); // Makes the JSON document
DeserializationError err = deserializeJson(doc, payload);
// Prints out the deserialization error if an error occurred
if (err) {
Serial.print("JSON DESERIALIZE ERROR: ");
Serial.println(err.c_str());
}
// Sets up the array from the JSON
JsonArray temperatureArray =
doc["fields"]["Temperature"]["arrayValue"]["values"];
// Creates a new array object to store the new temperature
JsonObject newTemp = temperatureArray.createNestedObject();
// Puts the new temperature in the new array object. For some reason,
// Firestore stores numbers as strings so the temperature is converted into
// a string.
newTemp["integerValue"] = String(temperature);
// Removes the first (oldest) array object.
temperatureArray.remove(0);
// Removes irrelevant data that we got from the Firestore request
doc.remove("name");
doc.remove("createTime");
doc.remove("updateTime");
String newJson;
serializeJson(doc, newJson);
Serial.println(newJson);
}
我如何将这个新的 JSON 发送回 Firestore?我这样做对吗?我听说过交易,这听起来像是理论上更好的方法来做我想做的事情,但我找不到任何关于如何做的指南或可读文档。我的数据库现在处于测试模式,因此无需担心身份验证。
解决方案
Firestore REST API 的文档在此处。
要创建文档,您需要向具有以下格式的 URL 发出 POST 请求:
https://firestore.googleapis.com/v1/{parent=projects/*/databases/*/documents/**}/{collectionId}
Document
在请求正文中有一个 a 的实例。
更具体地说,下面是一个简单 HTML 页面中的示例(使用Axios库发出 HTTP 请求)。collection1
此代码将在Firestore 集合中创建一个新文档。
只需将此文件保存在本地磁盘上,调整值<yourprojectID>
并在浏览器中直接从本地磁盘打开此页面。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<script>
var firebaseProjectId = '<yourprojectID>';
var collectionId = 'collection1';
var url =
'https://firestore.googleapis.com/v1/projects/' +
firebaseProjectId +
'/databases/(default)/documents/' +
collectionId;
var writeObj = {
fields: {
name: {
stringValue: 'theName'
},
initialBudget: {
doubleValue: 1200
}
}
};
axios.post(url, writeObj).catch(function(error) {
console.log(error);
});
</script>
</body>
</html>
为了更新现有文档中的数组,您必须使用FieldTransform
withappendMissingElements
元素。
此文档关于appendMissingElements
元素的摘录:
appendMissingElements
:如果给定的元素尚未出现在当前字段值中,则按顺序附加它们。如果该字段不是数组,或者该字段尚不存在,则首先将其设置为空数组。
FieldTransform
您将在下面找到包含appendMissingElements
元素的值示例。
{
"transform": {
"document": "projects/" + firebaseProjectId + "/databases/(default)/documents/....,
"fieldTransforms": [
{
"setToServerValue": "REQUEST_TIME",
"fieldPath": "lastUpdate"
},
{
"appendMissingElements": {
"values": [
{
"stringValue": "...."
}
]
},
"fieldPath": "fieldName"
}
]
}
}
根据您的评论更新
以下应该有效(经过积极测试):
var collectionId = 'SensorData';
var url =
'https://firestore.googleapis.com/v1/projects/' +
firebaseProjectId +
'/databases/(default)/documents:commit';
var writeObj = {
writes: {
transform: {
document:
'projects/' +
firebaseProjectId +
'/databases/(default)/documents/' +
collectionId +
'/Temperature',
fieldTransforms: [
{
setToServerValue: 'REQUEST_TIME',
fieldPath: 'lastUpdate'
},
{
appendMissingElements: {
values: [
{
integerValue: 25
}
]
},
fieldPath: 'Temperature'
}
]
}
}
};
推荐阅读
- javascript - React - 渲染道具,迭代数组不显示值
- wordpress - 从 wp-config.php 文件中提取数据库名称
- vue.js - 检查 Axios 是否有会话 cookie
- excel - 如何在数据透视表中添加虚拟数据行,以便在数据透视图中显示漂亮的趋势线?
- sql - 隐藏sql中的重复数据
- python - Jupyter Notebook 和 Lab 在 Anaconda Navigator 中不起作用
- python - 用漂亮的汤从网站中提取相似的项目
- python - 在 Python/Pandas 中执行数学运算符时处理 NA?
- bnf - 具有布尔代数的 Backus-Naur 形式。括号和解析树的问题
- c++ - 我的 godRays 片段着色器哪里出错了?