Flutter云数据库交互插件cloud_firestore_api的使用

Flutter云数据库交互插件cloud_firestore_api的使用

本包旨在为管理Flutter应用程序中的Firestore集合提供一个强大且灵活的基础类。通过扩展FirestoreApi类,您可以轻松地为特定的数据模型和集合创建自定义API类。

主要功能包括:

  • 🛠️ 所有基本的CRUD操作和流方法。
  • 🔎 方便的方法用于搜索/查询文档字段和数组的内容。
  • ⏰ 自动创建和更新创建和更新字段(非强制性)。
  • 📦 每个方法的批处理。
  • 📝 详细的日志记录和错误处理。
  • ✉️ 用户反馈消息以显示给用户(非强制性)。
  • 🦾 所有方法都可以使用或不使用数据转换器。
  • 🏙️ 所有方法也适用于集合组。
  • 💡 能够保存本地ID和文档引用,而无需将其添加到您的在线版本。

FirestoreApi 解释

FirestoreApi 构造函数有几个参数,允许您根据具体用例自定义 FirestoreApi 类的行为和功能。以下是每个参数的解释以及使用自定义 TasksApi 类的示例:

  1. firebaseFirestore: 一个必需的实例,来自 cloud_firestore 包的 FirebaseFirestore。这是您将用来与Firestore数据库交互的主要对象。
  2. collectionPath: 一个必需的函数,返回Firestore集合的路径作为字符串。这是特定API存储和检索数据的地方。这是一个回调,因此您可以在回调中动态更改此内容。
  3. fromJson: 一个可选函数,接受JSON映射作为输入并返回您的DTO类的一个实例。当从Firestore获取的JSON数据转换回您的DTO对象时调用此函数。
  4. toJson: 一个可选函数,接受类型为 T 的值作为输入并返回JSON映射。此函数用于将您的DTO对象转换为可以存储在Firestore中的映射。但是,此包使用一个名为 Writeable 的类来创建和更新文档。toJson 仅在调用原生 cloud_firestore 方法时才被调用。
  5. fromJsonError: 一个可选函数,接受JSON映射作为输入并返回您的DTO类的一个实例。当从Firestore获取的JSON数据反序列化失败时调用此函数。它允许您处理错误并提供默认的DTO对象,当JSON无效或转换失败时。
  6. tryAddLocalId: 一个可选布尔值,指示是否应在创建或更新文档时添加本地ID。设置为 true 如果您想在文档中包含本地ID,以便您的DTO始终期望它并始终访问本地ID。
  7. idFieldName: 一个可选字符串,设置Firestore文档中的本地ID字段名称。在 tryAddLocalId 为 true 时使用。
  8. tryAddLocalDocumentReference: 一个可选布尔值,指示是否应在创建或更新文档时添加本地 DocumentReference。设置为 true 如果您想在文档中包含本地 DocumentReference,以便您的DTO始终期望它并始终访问 DocumentReference 本地。
  9. documentReferenceFieldName: 一个可选字符串,设置Firestore文档中的本地 DocumentReference 字段名称。在 tryAddLocalDocumentReference 为 true 时使用。
  10. feedbackConfig: 一个可选的 FeedbackConfig 对象,允许您配置各种CRUD操作的用户反馈消息。
  11. firestoreLogger: 一个可选的 FirestoreLogger 对象,可用于记录与 FirestoreApi 相关的调试信息、成功、警告、值和错误消息。这是一个抽象类,您可以继承它,以便将日志传递到自己的系统中。
  12. createdFieldName: 一个可选字符串,设置Firestore文档中的“创建”时间戳字段名称。是否在创建文档时向文档添加该字段由 create 方法指定。
  13. updatedFieldName: 一个可选字符串,设置Firestore文档中的“更新”时间戳字段名称。是否在创建文档时向文档添加该字段由 create 和 update 方法指定。
  14. isCollectionGroup: 一个可选布尔值,指示API是否应与Firestore集合组一起工作。设置为 true 如果您正在处理集合组,并且所有方法将以与处理常规集合相同的方式工作。

TaskApi 示例

class TasksApi extends FirestoreApi<TaskDTO> {
  TasksApi({required FirebaseFirestore firebaseFirestore})
      : super(
    firebaseFirestore: firebaseFirestore,
    collectionPath: () => 'tasks',
    toJson: TaskDTO.toJson,
    fromJson: TaskDTO.fromJson,
    fromJsonError: TaskDTO.fromJsonError,
    tryAddLocalId: true,
    feedbackConfig: FeedbackConfig(),
    firestoreLogger: FirestoreLogger(),
    createdFieldName: 'created',
    updatedFieldName: 'updated',
    idFieldName: 'id',
    documentReferenceFieldName: 'documentReference',
    isCollectionGroup: false,
    tryAddLocalDocumentReference: true,
  );
}

TaskDto 示例

class TaskDto {
  final String id;
  final String title;
  final String description;
  final DateTime created;
  final DateTime updated;
  final DocumentReference? documentReference;

  TaskDto({
    required this.id,
    required this.title,
    required this.description,
    required this.created,
    required this.updated,
    this.documentReference,
  });

  // 将 TaskDTO 转换为 JSON 映射
  static Map<String, dynamic> toJson(TaskDTO task) {
    return {
      'id': task.id,
      'title': task.title,
      'description': task.description,
      'created': task.created.toUtc(),
      'updated': task.updated.toUtc(),
      'documentReference': task.documentReference,
    };
  }

  // 将 JSON 映射转换为 TaskDTO
  static TaskDTO fromJson(Map<String, dynamic> json) {
    return TaskDTO(
      id: json['id'] as String,
      title: json['title'] as String,
      description: json['description'] as String,
      created: (json['created'] as Timestamp).toDate(),
      updated: (json['updated'] as Timestamp).toDate(),
      documentReference: json['documentReference'] as DocumentReference?,
    );
  }

  // 处理无效的 JSON 数据并返回默认的 TaskDTO 对象
  static TaskDTO fromJsonError(Map<String, dynamic> json) {
    return TaskDTO(
      id: '',
      title: '未知',
      description: '获取此任务时发生未知错误',
      created: DateTime.now(),
      updated: DateTime.now(),
      documentReference: null,
    );
  }
}

反馈响应

FeedbackResponse 对象是一种通用且可定制的方式来处理应用程序中各种操作的结果。它封装了操作的结果,并提供了有关其成功、错误或其他反馈级别的有用信息。它还可以存储与操作相关的其他数据,例如Firestore查询的结果。

FeedbackResponse 对象的结构

  1. FeedbackLevel: 这是一个枚举,表示响应的反馈级别,如成功、信息、警告或错误。它有助于对操作结果的类型进行分类。
  2. FeedbackType: 这是另一个枚举,表示反馈应该如何呈现给用户,例如作为通知、对话框或无反馈。
  3. Title 和 Message: 这些可选字段可以包含字符串,以提供更多关于操作结果的信息。它们可以用于UI中向用户显示消息或标题。
  4. Result: 这是一个可选字段,可以存储操作的实际结果,例如从Firestore获取的文档或文档列表。
  5. 工厂方法: FeedbackResponse 类提供了几个工厂方法,如 success、successNone、info、warning、error 和 errorNone,这些方法帮助基于所需的反馈级别和类型创建特定的 FeedbackResponse 实例。
  6. isSuccess: 这是一个获取器,返回一个布尔值,指示反馈级别是否为成功或信息。
  7. copyWith: 此方法允许您基于现有对象创建一个新的 FeedbackResponse 对象,但某些字段已更改。当您需要基于现有对象创建一个新响应但需要少量修改时,这很有用。
  8. fold: 此方法提供了一种执行两个提供的回调之一的方法,具体取决于 isSuccess 属性是真还是假。它简化了代码中成功和错误情况的处理。

示例代码

class FeedbackService {
  void showFeedback(FeedbackResponse response) {
    switch (response.feedbackType) {
      case FeedbackType.notification:
        _showNotification(response);
        break;
      case FeedbackType.dialog:
        _showDialog(response);
        break;
      case FeedbackType.none:
        break;
    }
  }

  void _showNotification(FeedbackResponse response) {
    print('显示通知: ${response.title} - ${response.message}');
  }

  void _showDialog(FeedbackResponse response) {
    print('显示对话框: ${response.title} - ${response.message}');
  }
}

void main() async {
  TasksApi tasksApi = TasksApi();
  FeedbackService feedbackService = FeedbackService();

  FeedbackResponse<TaskDTO> response = await tasksApi.findTaskByIdWithConverter('taskId123');

  response.fold(
    ifSuccess: (successfulResponse) {
      // 处理成功
      TaskDTO task = successfulResponse.result!;
      print('任务成功获取: ${task.title}');

      // 显示成功反馈
      feedbackService.showFeedback(successfulResponse);
    },
    ifError: (errorResponse) {
      // 处理错误
      print('未能获取任务: ${errorResponse.message}');

      // 显示错误反馈
      feedbackService.showFeedback(errorResponse);
    },
  );
}

查找方法

Firestore API 提供了一系列强大的方法,用于在Firestore集合中查找文档。这些方法提供了多种方式根据文档的唯一标识符检索文档,同时还提供了使用转换器进行自定义数据处理的选项。借助这些查找方法,您可以轻松地从Firestore获取文档,处理错误,并向用户提供适当的反馈。

通过ID查找

findByIdWithConverter 方法根据给定的文档ID从Firestore集合中获取文档,并应用一个转换函数(作为参数提供)将原始JSON数据转换为自定义Dart对象(在这种情况下为 TaskDTO)。它返回一个 FeedbackResponse 对象,其中包含作为自定义Dart对象实例的转换后的数据。

示例代码

class TasksAPI extends FirestoreAPI<TaskDTO> {
  // 构造函数和其他方法

  Future<FeedbackResponse<TaskDTO>> findTaskByIdWithConverter(String taskId) async {
    return await findByIdWithConverter(id: taskId);
  }
}

通过搜索词查找

findBySearchTermWithConverter 方法用于根据特定搜索词、字段和搜索词类型在Firestore集合中搜索文档。该方法返回 FeedbackResponse<List<T>>,其中 T 是您正在处理的数据模型的类型。此方法使用转换器处理Firestore与您的数据模型之间的数据转换。

示例代码

class TaskDto {
  // 任务属性
}

class TaskApi extends FirestoreApi<TaskDto> {
  TaskApi()
      : super(
            // 初始化参数
          );

  // 其他 TaskApi 方法
}

void main() async {
  final taskApi = TaskApi();

  final searchTerm = 'Sample Task';
  final searchField = 'title';
  final searchTermType = SearchTermType.String;

  final response = await taskApi.findBySearchTermWithConverter(
    searchTerm: searchTerm,
    searchField: searchField,
    searchTermType: searchTermType,
  );

  response.fold(
    ifSuccess: (result) {
      FeedbackService.showSuccess('找到的任务', '以下任务已被找到:');
      for (var task in result.result) {
        print(task);
      }
    },
    ifError: (errorResponse) {
      FeedbackService.showError('错误', '未能获取任务。');
    },
  );
}

通过查询查找

findByQueryWithConverter 方法用于通过提供自定义查询在Firestore集合中搜索文档。该方法返回 FeedbackResponse<List<T>>,其中 T 是您正在处理的数据模型的类型。此方法使用转换器处理Firestore与您的数据模型之间的数据转换。

示例代码

class TaskDto {
  // 任务属性
}

class TaskApi extends FirestoreApi<TaskDto> {
  TaskApi()
      : super(
            // 初始化参数
          );

  // 其他 TaskApi 方法
}

void main() async {
  final taskApi = TaskApi();

  final dueDate = DateTime.now().add(Duration(days: 7));

  final response = await taskApi.findByQueryWithConverter(
    collectionReferenceQuery: (collectionReference) {
      return collectionReference.where('dueDate', isLessThanOrEqualTo: dueDate);
    },
    whereDescription: 'dueDate is less than or equal to $dueDate',
  );

  response.fold(
    ifSuccess: (result) {
      FeedbackService.showSuccess('找到的任务', '以下任务已被找到:');
      for (var task in result.result) {
        print(task);
      }
    },
    ifError: (errorResponse) {
      FeedbackService.showError('错误', '未能获取任务。');
    },
  );
}

查找所有

findAllWithConverter 方法用于从Firestore集合中获取所有文档。该方法返回 FeedbackResponse<List<T>>,其中 T 是您正在处理的数据模型的类型。此方法使用转换器处理Firestore与您的数据模型之间的数据转换。

示例代码

class TaskDto {
  // 任务属性
}

class TaskApi extends FirestoreApi<TaskDto> {
  TaskApi()
      : super(
            // 初始化参数
          );

  // 其他 TaskApi 方法
}

void main() async {
  final taskApi = TaskApi();

  final response = await taskApi.findAllWithConverter();

  response.fold(
    ifSuccess: (result) {
      FeedbackService.showSuccess('找到的任务', '以下任务已被找到:');
      for (var task in result.result) {
        print(task);
      }
    },
    ifError: (errorResponse) {
      FeedbackService.showError('错误', '未能获取任务。');
    },
  );
}

流和其它查找方法

  • findCollectionWithConverter 和 findCollection:

    • findCollectionWithConverter: 使用指定的 _fromJson 和 _toJson 方法检索类型为 T 的集合。示例用法:

      final collection = firestoreApi.findCollectionWithConverter<T>();
      
    • findCollection: 检索类型为 Map 的集合。示例用法:

      final collection = firestoreApi.findCollection();
      
  • findDocRefWithConverter 和 findDocRef:

    • findDocRefWithConverter: 使用指定的 _fromJson 和 _toJson 方法检索类型为 T 的文档引用。示例用法:

      final docRef = firestoreApi.findDocRefWithConverter<T>(id: 'doc_id');
      
    • findDocRef: 检索类型为 Map 的文档引用。示例用法:

      final docRef = firestoreApi.findDocRef(id: 'doc_id');
      
  • findDocSnapshotWithConverter 和 findDocSnapshot:

    • findDocSnapshotWithConverter: 使用指定的 _fromJson 和 _toJson 方法检索类型为 T 的文档快照。示例用法:

      final docSnapshot = await firestoreApi.findDocSnapshotWithConverter<T>(id: 'doc_id');
      
    • findDocSnapshot: 检索类型为 Map 的文档快照。示例用法:

      final docSnapshot = await firestoreApi.findDocSnapshot(id: 'doc_id');
      
  • findStreamWithConverter 和 findStream:

    • findStreamWithConverter: 使用指定的 _fromJson 和 _toJson 方法检索类型为 T 的流列表。示例用法:

      final stream = firestoreApi.findStreamWithConverter<T>();
      
    • findStream: 检索类型为 Map 的流列表。示例用法:

      final stream = firestoreApi.findStream();
      
  • findStreamByQueryWithConverter 和 findStreamByQuery:

    • findStreamByQueryWithConverter: 基于给定的 collectionReferenceQuery 和 whereDescription,使用指定的 _fromJson 和 _toJson 方法检索类型为 T 的流列表。示例用法:

      final stream = firestoreApi.findStreamByQueryWithConverter<T>(
        collectionReferenceQuery: (collection) => collection.where('field', isEqualTo: 'value'),
        whereDescription: "field == value",
      );
      
    • findStreamByQuery: 基于给定的 collectionReferenceQuery 和 whereDescription,检索类型为 Map 的流列表。示例用法:

      final stream = firestoreApi.findStreamByQuery(
        collectionReferenceQuery: (collection) => collection.where('field', isEqualTo: 'value'),
        whereDescription: "field == value",
      );
      
  • findDocStreamWithConverter 和 findDocStream:

    • findDocStreamWithConverter: 使用指定的 _fromJson 和 _toJson 方法检索类型为 T 的文档流。示例用法:

      final docStream = firestoreApi.findDocStreamWithConverter<T>(id: 'doc_id');
      
    • findDocStream: 检索类型为 Map 的文档流。示例用法:

      final docStream = firestoreApi.findDocStream(id: 'doc_id');
      

Writeable

Writeable 类是一个抽象类,用于表示可以写入Firestore的数据对象。通过创建自定义类并扩展 Writeable 类,开发人员可以确保他们的数据模型与Firestore API兼容,同时为他们的代码提供清晰的结构。Writeable 类的主要功能包括:

  1. toJson(): 应覆盖在扩展 Writeable 类的自定义类中。它负责将数据对象转换为JSON格式,可以写入Firestore。
  2. isValidResponse(): 返回一个 FeedbackResponse 对象,提供有关数据对象有效性的信息,包括成功标志、标题和消息。通常由API中的 create 和 update 方法内部调用,以确保在尝试将数据写入Firestore之前数据有效。

示例代码

class UpdateTaskRequest extends Writeable {
  final String title;
  final String description;
  final bool isCompleted;

  UpdateTaskRequest({required this.title, required this.description, this.isCompleted = false});

  @override
  Map<String, dynamic> toJson() {
    return {
      'title': title,
      'description': description,
      'isCompleted': isCompleted,
    };
  }

  @override
  FeedbackResponse isValidResponse() {
    if (title.isNotEmpty && description.isNotEmpty) {
      return FeedbackResponse.successNone();
    } else {
      return FeedbackResponse.error(
        title: '无效任务',
        message: '任务标题和描述不能为空。',
      );
    }
  }
}

在此示例中,如果任务的 title 和 description 不为空,则认为任务有效。toJson 方法将任务对象转换为适合Firestore的JSON格式。在使用API中的 create 或 update 方法时,现在可以将 UpdateTaskRequest 类作为 Writeable 对象传递。

创建和更新方法

我们提供了自定义的 create 和 update 方法,旨在简化与Firestore的工作。create 方法允许您基于 Writeable 对象创建新的文档,而 update 方法则允许您使用类似的方法修改现有文档。这两种方法还提供了其他功能,如支持批操作、自动处理时间戳字段、合并和合并字段选项,以及用于集合组的集合路径覆盖。

创建和批量创建

create 方法设计用于基于给定的 Writeable 对象在Firestore集合中创建或更新文档。它提供了设置自定义ID、使用 WriteBatch 对象以及控制创建和更新时间戳的选项。此外,您可以使用 merge 和 mergeFields 选项来控制更新行为。如果 create 方法使用 WriteBatch 调用,则委托给 batchCreate 方法。

示例代码

class UpdateTaskRequest extends Writeable {
  final String title;
  final String description;
  final bool isCompleted;

  UpdateTaskRequest({required this.title, required this.description, this.isCompleted = false});

  @override
  Map<String, dynamic> toJson() {
    return {
      'title': title,
      'description': description,
      'isCompleted': isCompleted,
    };
  }

  @override
  FeedbackResponse isValidResponse() {
    if (title.isNotEmpty && description.isNotEmpty) {
      return FeedbackResponse.successNone();
    } else {
      return FeedbackResponse.error(
        title: '无效任务',
        message: '任务标题和描述不能为空。',
      );
    }
  }
}

class TaskDto implements Writeable {
  // 你的 TaskDto 实现
}

class TaskApi extends FirestoreApi<TaskDto> {
  TaskApi()
      : super(
            // 初始化参数
          );

  // 其他 TaskApi 方法
}

void main() async {
  TaskApi taskApi = TaskApi();
  TaskDto taskDto = TaskDto(/* 你的 TaskDto 数据 */);

  // 使用 create 方法创建新的任务文档
  FeedbackResponse<DocumentReference> response = await taskApi.createDoc(writeable: taskDto);
  if (response.isSuccess) {
    print('任务文档创建成功,ID: ${response.result!.id}');
  } else {
    print('创建任务文档失败: ${response.message}');
  }

  // 更新现有的任务文档
  String taskId = 'your-task-id'; // 替换为实际的任务ID
  UpdateTaskRequest updateRequest = UpdateTaskRequest(title: '新标题', description: '新描述');
  FeedbackResponse<void> updateResponse = await taskApi.updateDoc(id: taskId, writeable: updateRequest);
  if (updateResponse.isSuccess) {
    print('任务文档更新成功');
  } else {
    print('更新任务文档失败: ${updateResponse.message}');
  }

  // 创建 WriteBatch
  WriteBatch writeBatch = FirebaseFirestore.instance.batch();

  // 使用 batchCreate 方法向 WriteBatch 添加多个任务
  TaskDto taskDto2 = TaskDto(/* 你的 TaskDto 数据 */);
  TaskDto taskDto3 = TaskDto(/* 你的 TaskDto 数据 */);

  await taskApi.batchCreate(writeable: taskDto2, writeBatch: writeBatch);
  await taskApi.batchCreate(writeable: taskDto3, writeBatch: writeBatch);

  // 提交 WriteBatch
  await writeBatch.commit();
  print('WriteBatch 提交成功');
}

create 方法和 batchCreate 方法的主要区别在于 create 方法直接将数据提交到Firestore,而 batchCreate 方法将数据添加到Firestore的 WriteBatch 中。WriteBatch 可以稍后提交以在单个事务中执行多个写入。

更新和批量更新

update 方法设计用于基于给定的 Writeable 对象和文档ID更新Firestore集合中的现有文档。它提供了使用 WriteBatch 对象以及控制更新时间戳的选项。此外,您可以使用 merge 和 mergeFields 选项来控制更新行为。如果 update 方法使用 WriteBatch 调用,则委托给 batchUpdate 方法。

示例代码

class UpdateTaskRequest extends Writeable {
  final String title;
  final String description;
  final bool isCompleted;

  UpdateTaskRequest({required this.title, required this.description, this.isCompleted = false});

  @override
  Map<String, dynamic> toJson() {
    return {
      'title': title,
      'description': description,
      'isCompleted': isCompleted,
    };
  }

  @override
  FeedbackResponse isValidResponse() {
    if (title.isNotEmpty && description.isNotEmpty) {
      return FeedbackResponse.successNone();
    } else {
      return FeedbackResponse.error(
        title: '无效任务',
        message: '任务标题和描述不能为空。',
      );
    }
  }
}

class TaskDto implements Writeable {
  // 你的 TaskDto 实现
}

class TaskApi extends FirestoreApi<TaskDto> {
  TaskApi()
      : super(
            // 初始化参数
          );

  // 其他 TaskApi 方法
}

void main() async {
  TaskApi taskApi = TaskApi();
  String taskId = 'your-task-id'; // 替换为实际的任务ID
  UpdateTaskRequest updateRequest = UpdateTaskRequest(title: '新标题', description: '新描述');

  // 使用 update 方法更新任务文档
  FeedbackResponse<void> updateResponse = await taskApi.updateDoc(id: taskId, writeable: updateRequest);
  if (updateResponse.isSuccess) {
    print('任务文档更新成功');
  } else {
    print('更新任务文档失败: ${updateResponse.message}');
  }

  // 创建 WriteBatch
  WriteBatch writeBatch = FirebaseFirestore.instance.batch();

  // 使用 batchUpdate 方法向 WriteBatch 添加多个任务
  String taskId2 = 'your-task-id-2'; // 替换为实际的任务ID
  String taskId3 = 'your-task-id-3'; // 替换为实际的任务ID
  UpdateTaskRequest updateRequest2 = UpdateTaskRequest(title: '新标题 2', description: '新描述 2');
  UpdateTaskRequest updateRequest3 = UpdateTaskRequest(title: '新标题 3', description: '新描述 3', isCompleted: true);

  await taskApi.batchUpdate(id: taskId2, writeable: updateRequest2, writeBatch: writeBatch);
  await taskApi.batchUpdate(id: taskId3, writeable: updateRequest3, writeBatch: writeBatch);

  // 提交 WriteBatch
  await writeBatch.commit();
  print('WriteBatch 提交成功');
}

update 方法和 batchUpdate 方法的主要区别在于 update 方法直接将数据提交到Firestore,而 batchUpdate 方法将数据添加到Firestore的 WriteBatch 中。WriteBatch 可以稍后提交以在单个事务中执行多个更新。

删除和批量删除

delete 方法设计用于基于给定的ID从Firestore集合中删除文档。它提供了使用 WriteBatch 对象以及覆盖 collectionPath 的选项。如果 delete 方法使用 WriteBatch 调用,则委托给 batchDelete 方法。

示例代码

class TaskApi extends FirestoreApi<TaskDto> {
  TaskApi()
      : super(
            // 初始化参数
          );

  // 其他 TaskApi 方法
}

void main() async {
  TaskApi taskApi = TaskApi();

  // 使用 delete 方法删除任务文档
  String taskId = 'your-task-id'; // 替换为实际的任务ID
  FeedbackResponse<void> deleteResponse = await taskApi.deleteDoc(id: taskId);
  if (deleteResponse.isSuccess) {
    print('任务文档删除成功');
  } else {
    print('删除任务文档失败: ${deleteResponse.message}');
  }

  // 创建 WriteBatch
  WriteBatch writeBatch = FirebaseFirestore.instance.batch();

  // 使用 batchDelete 方法向 WriteBatch 添加多个任务删除
  String taskId2 = 'your-task-id-2'; // 替换为实际的任务ID
  String taskId3 = 'your-task-id-3'; // 替换为实际的任务ID

  await taskApi.batchDelete(id: taskId2, writeBatch: writeBatch);
  await taskApi.batchDelete(id: taskId3, writeBatch: writeBatch);

  // 提交 WriteBatch
  await writeBatch.commit();
  print('WriteBatch 提交成功');
}

更多关于Flutter云数据库交互插件cloud_firestore_api的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter云数据库交互插件cloud_firestore_api的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


cloud_firestore 是 Flutter 中用于与 Firestore 数据库进行交互的官方插件。Firestore 是 Google Firebase 提供的一种 NoSQL 云数据库,支持实时数据同步和高效的数据查询。以下是如何在 Flutter 项目中使用 cloud_firestore 插件进行基本操作的指南。

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 cloud_firestore 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  firebase_core: latest_version
  cloud_firestore: latest_version

然后运行 flutter pub get 来安装依赖。

2. 初始化 Firebase

在使用 Firestore 之前,你需要初始化 Firebase。通常在 main.dart 文件中进行初始化:

import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Firestore Demo',
      home: MyHomePage(),
    );
  }
}

3. 基本操作

添加数据

你可以使用 add 方法来向 Firestore 中添加数据:

import 'package:cloud_firestore/cloud_firestore.dart';

Future<void> addUser(String name, int age) async {
  CollectionReference users = FirebaseFirestore.instance.collection('users');
  return users.add({
    'name': name,
    'age': age,
  })
  .then((value) => print("User Added"))
  .catchError((error) => print("Failed to add user: $error"));
}

查询数据

你可以使用 get 方法来查询数据:

Future<void> getUser() async {
  CollectionReference users = FirebaseFirestore.instance.collection('users');
  QuerySnapshot querySnapshot = await users.get();

  querySnapshot.docs.forEach((doc) {
    print(doc.data());
  });
}

更新数据

你可以使用 update 方法来更新数据:

Future<void> updateUser(String userId, String newName) async {
  CollectionReference users = FirebaseFirestore.instance.collection('users');
  return users.doc(userId).update({
    'name': newName,
  })
  .then((value) => print("User Updated"))
  .catchError((error) => print("Failed to update user: $error"));
}

删除数据

你可以使用 delete 方法来删除数据:

Future<void> deleteUser(String userId) async {
  CollectionReference users = FirebaseFirestore.instance.collection('users');
  return users.doc(userId).delete()
  .then((value) => print("User Deleted"))
  .catchError((error) => print("Failed to delete user: $error"));
}

4. 实时数据监听

Firestore 支持实时数据更新。你可以使用 snapshots 方法来监听数据的变化:

StreamBuilder<QuerySnapshot>(
  stream: FirebaseFirestore.instance.collection('users').snapshots(),
  builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
    if (snapshot.hasError) {
      return Text('Something went wrong');
    }

    if (snapshot.connectionState == ConnectionState.waiting) {
      return Text("Loading");
    }

    return ListView(
      children: snapshot.data!.docs.map((DocumentSnapshot document) {
        Map<String, dynamic> data = document.data()! as Map<String, dynamic>;
        return ListTile(
          title: Text(data['name']),
          subtitle: Text(data['age'].toString()),
        );
      }).toList(),
    );
  },
)
回到顶部