You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用生成唯一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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 21:42:43