调用生成唯一ID函数仍遇Appwrite文档ID已存在错误
问题描述
通过Arduino代码调用Appwrite REST API创建文档时,遇到以下异常:
- 自定义生成20位随机
documentId,打印payload确认该ID在数据库中不存在,但Appwrite返回409错误:{"message":"Document with the requested ID already exists. Try again with a different ID or use ID.unique() to generate a unique ID.","code":409,"type":"document_already_exists","version":"1.6.1"} - 尝试传入
unique()作为documentId值,仍触发相同错误 - 省略
documentId字段时,Appwrite提示'documentId' field is required
代码片段
String generateRandomId(int length) { const char charset[] = "0123456789abcdefghijklmnopqrstuvwxyz"; // Alphanumeric characters for ID String id = ""; for (int i = 0; i < length; i++) { int index = random(0, sizeof(charset) - 1); // Ensure the index stays within bounds id += charset[index]; // Append the character to the ID string } return id; } void createNotification(String type, String message) { if (WiFi.status() == WL_CONNECTED) { if (!userCoop.coopDocId.isEmpty() && !userCoop.medicineModuleDeviceId.isEmpty() && !type.isEmpty() && !message.isEmpty() && !dateTime.isEmpty()) { WiFiClientSecure client; client.setInsecure(); HTTPClient http; // Construct the full URL String url = String(appwriteEndpoint) + "/v1/databases/" + databaseId + "/collections/" + notificationCollectionId + "/documents"; http.begin(client, url); // Specify the destination for the HTTP request // Set the required headers for the Appwrite request http.addHeader("Content-Type", "application/json"); http.addHeader("X-Appwrite-Response-Format", "1.6.0"); http.addHeader("X-Appwrite-Project", projectId); http.addHeader("X-Appwrite-Key", apiKey); // Create JSON object StaticJsonDocument<512> doc; doc["documentId"] = generateRandomId(20); JsonObject data = doc.createNestedObject("data"); data["deviceId"] = userCoop.medicineModuleDeviceId; data["coopId"] = userCoop.coopDocId; data["type"] = type; data["message"] = message; data["createdAt"] = dateTime; data["isRead"] = false; // Serialize JSON to string String payload; serializeJson(doc, payload); Serial.println("Payload: " + payload); // Debug payload // Send the POST request int httpResponseCode = http.POST(payload); // Check the response code if (httpResponseCode > 0) { String response = http.getString(); // Get the response payload Serial.println("\nCreate Notification Response code: " + String(httpResponseCode)); Serial.println("Create Notification Response: " + response); } else { Serial.println("\nError on HTTP Create Notification request"); Serial.println("HTTP Response code: " + String(httpResponseCode)); } http.end(); } else { Serial.println("createNotification: Empty variables"); } } else { Serial.println("WiFi not connected"); } }
解决方案
1. 修复随机ID生成的种子问题
Arduino的random()函数默认未初始化随机种子,设备重启后会生成固定序列的ID,这是导致重复ID的核心原因。
在setup()中添加随机种子初始化代码:
void setup() { // 其他初始化逻辑... randomSeed(analogRead(0)); // 利用模拟引脚噪声生成随机种子 }
2. 正确使用Appwrite的自动生成ID功能
Appwrite REST API中,要让系统自动生成唯一ID,需将documentId设置为字符串"unique"(小写,不带括号),而非"unique()":
// 替换原doc["documentId"] = generateRandomId(20); doc["documentId"] = "unique";
3. 新增ID预检查逻辑(可选)
如果需要确保自定义ID绝对不重复,可以在生成ID后调用Appwrite的查询接口提前验证:
bool isDocumentIdExists(String docId) { WiFiClientSecure client; client.setInsecure(); HTTPClient http; String url = String(appwriteEndpoint) + "/v1/databases/" + databaseId + "/collections/" + notificationCollectionId + "/documents/" + docId; http.begin(client, url); http.addHeader("X-Appwrite-Project", projectId); http.addHeader("X-Appwrite-Key", apiKey); int httpCode = http.GET(); bool exists = (httpCode == 200); // 200表示ID已存在,404表示不存在 http.end(); return exists; } // 在createNotification中使用 String newDocId; do { newDocId = generateRandomId(20); } while(isDocumentIdExists(newDocId)); doc["documentId"] = newDocId;
4. 检查集合配置
登录Appwrite控制台,确认目标集合的文档ID策略设置为「自定义」,如果设置为「自动生成」,传入自定义ID会触发错误。
内容的提问来源于stack exchange,提问作者Diane Gutierrez
相关产品推荐
相关产品推荐

