Flutter文件服务插件fs_service的使用

发布于 1周前 作者 wuwangju 来自 Flutter

Flutter文件服务插件fs_service的使用

目标

本插件旨在与Firestore中的数据进行交互。它具有以下功能:

  • 导入 Firestore 文档和集合,并将其打印到控制台或写入 JSON 文件。
  • 从控制台或 JSON 文件导出文档和集合到 Firestore。
  • 删除 Firestore 文档和集合。
  • 执行所有这些操作并保持内部结构,同时保留 Firestore 中的所有数据类型。

添加工具到项目

将此行手动添加到 dev_dependencies:

dev_dependencies:
  fs_service: ^1.0.0

或者在应用程序根目录(包含 pubspec.yaml 文件)中运行此命令:

dart pub add dev:fs_service

获取 Firestore 项目的访问权限

为了访问数据,需要使用 Firestore 服务账户。所需步骤如下:

  1. 创建 Firestore 项目的服务账户。
  2. 下载用于访问该账户的 JSON 证书文件。
  3. 设置 GOOGLE_APPLICATION_CREDENTIALS 环境变量,并指定证书文件路径。

例如:

export GOOGLE_APPLICATION_CREDENTIALS=secret/myProject-firebase-adminsdk-asda-23423hgh32.json

更多关于这方面的信息,请参阅:https://cloud.google.com/docs/authentication/application-default-credentials#GAC

Firestore 中文档和集合的一般结构

请注意,结构如下所示:

  • 文档位于项目的根目录下。
  • 每个文档由不同类型的字段组成。
  • 每个文档可以有一个嵌套的集合,而不仅仅是单一的集合。
  • 多个文档可以嵌套在每个集合中。

重要结论:

  • 如果 colX 是集合的名称,docX 是文档的名称,则从根目录开始的相对路径看起来像这样:col1/doc1/col2/doc2,即路径以集合开始,交替包含文档和 嵌套在文档中的集合。
  • 只能向集合添加文档,反之亦然。
  • 如果删除集合 col1,则会删除该路径下的所有文档和 集合。
  • 如果删除文档 doc1,则会删除该路径下的所有集合和 文档。

根目录的绝对路径如下:

projects/{projectId}/databases/{databaseId}/documents

您需要传递 projectId 的值(可选时传递 databaseId 值),作为应用程序的参数,如示例所示。

get-doc 命令

这是一个名为 lUAEoKptpXKT1CshnZKX 的的文档示例,其中包含 Firestore 提供的所有类型的字段。还有一个一个嵌套的集合,包含一个文档 lUAEoKptpXKT1CshnZKX/col1/lUAEoKptpXKTaCshnZKX - 第一个文档的一个副本。

示例代码如下:

dart run fs_service get-doc test/lUAEoKptpXKT1CshnZKX --project=myProject

由于未指定输出文件选项,结果将打印到标准输出:

{
  "numberF": 1234.5432,
  "null1": null,
  "ref": "reference://projects/myProject/databases/(default)/documents/en/YLTunxHK6rgPTWHxjJYe",
  "timestamp": "datetime://2023-10-21T11:26:40.152Z",
  "translit": "",
  "geopointt": "location://34.3456/-23.432",
  "word": "four",
  "map": {
    "key1": {
      "key2": "value2"
    }
  },
  "transcript": "fɔːr",
  "boolean": true,
  "number": 12345,
  "array": [
    "array1",
    "array2"
  ],
  "id": "95il61U47MVonL027u3V",
  "$name": "lUAEoKptpXKT1CshnZKX",
  "$createTime": "2023-10-26T12:52:01.608133Z",
  "$updateTime": "2023-10-26T12:52:01.608133Z",
  "$collections": [
    {
      "$name": "col1",
      "$documents": [
        {
          "map": {
            "key1": {
              "key2": "value2"
            }
          },
          "number": 12345,
          "transcript": "fɔːr",
          "word": "four",
          "ref": "reference://projects/myProject/databases/(default)/documents/en/YLTunxHK6rgPTWHxjJYe",
          "numberF": 1234.5432,
          "id": "95il61U47MVonL027u3V",
          "translit": "",
          "geopoint": "location://34.3456/-23.432",
          "boolean": true,
          "array": [
            "array1",
            "array2"
          ],
          "null1": null,
          "timestamp": "datetime://2023-10-21T11:26:40.152Z",
          "$name": "lUAEoKptpXKTaCshnZKx",
          "$createTime": "2024-01-02T11:40:47.284577Z",
          "$updateTime": "2024-01-02T11:40:47.284577Z"
        }
      ]
    }
  ]
}

更复杂的示例可以在 doc-2.jsoncol-2.json 文件中找到。

时间总是转换为 UTC 以避免混淆。 默认的地理位置存储形式为 location://{LATITUDE}/{LONGITUDE}

默认情况下,以 $ 开头的字段是元数据字段。这些字段用于恢复 Firestore 数据库的结构。

如果您的数据库字段名与元数据字段名冲突,您可以更改元数据前缀。运行以下命令以了解更多信息:

dart run fs_service help get-doc

如果您对 reference:// 和其他此类前缀不满意,也可以通过工具选项进行更改。

add-doc 命令

如果使用上述 get-doc 命令的示例,并通过管道 (|) 运行 add-doc 命令, 那么 get-doc 命令的结果将被传递给 add-doc 命令。

示例代码如下:

dart run fs_service get-doc test/lUAEoKptpXKT1CshnZKX --project=myProject | \
  dart run fs_service add-doc test -c doc4 --project=ella500

在这种情况下,文档 test/lUAEoKptpXKTaCshnZKx 将复制到同一集合 test,但名称为 doc4(选项 -c)。 所有嵌套的集合和文档也将被复制。

注意:$createTime$updateTime 字段的值不会写入 Firestore 文档,因为 Firestore 忽略这些值并自动覆盖它们。

提示:您可以删除文档的元数据字段 $name 或将其设置为 null。在这种情况下,Firestore 将为其分配随机唯一的 ID。

del-doc 命令

用于删除文档及其所有嵌套的集合和文档。

示例代码如下:

dart run fs_service del-doc test/lUAEoKptpXKTaCshnZKx --project=myProject

小心,因为操作会导致数据不可恢复地丢失。

get-col, add-col 和 del-col 命令

它们的工作方式类似于 get-docadd-docdel-doc 命令,但设计用于处理集合。

更多详细信息

有关工具和每个命令的详细信息,请运行以下命令:

dart run fs_service --help
dart run fs_service help add-doc

更多关于Flutter文件服务插件fs_service的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter文件服务插件fs_service的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用fs_service插件进行文件服务的示例代码。fs_service插件允许你访问设备的文件系统,进行文件的读写操作。请确保你已经在pubspec.yaml文件中添加了fs_service依赖,并运行flutter pub get来获取依赖。

pubspec.yaml

dependencies:
  flutter:
    sdk: flutter
  fs_service: ^最新版本号  # 请替换为实际的最新版本号

main.dart

import 'package:flutter/material.dart';
import 'package:fs_service/fs_service.dart';
import 'dart:io';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final FileSystemService _fileSystemService = FileSystemService();
  String _fileContent = '';
  File? _file;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter File Service Example'),
        ),
        body: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            children: [
              TextField(
                decoration: InputDecoration(labelText: 'File Content'),
                maxLines: 10,
                controller: TextEditingController(text: _fileContent),
                onChanged: (value) {
                  setState(() {
                    _fileContent = value;
                  });
                },
              ),
              SizedBox(height: 16),
              ElevatedButton(
                onPressed: () async {
                  // Create or Open File
                  _file = File('${(await getApplicationDocumentsDirectory()).path}/example.txt');
                  await _file!.writeAsString(_fileContent);
                  ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('File saved')));
                },
                child: Text('Save File'),
              ),
              SizedBox(height: 16),
              ElevatedButton(
                onPressed: () async {
                  if (_file != null && await _file!.exists()) {
                    String content = await _file!.readAsString();
                    setState(() {
                      _fileContent = content;
                    });
                    ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('File read')));
                  } else {
                    ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('File does not exist')));
                  }
                },
                child: Text('Read File'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

解释

  1. 依赖管理:在pubspec.yaml文件中添加fs_service依赖。
  2. 文件系统服务:使用FileSystemService类,但实际上在这个例子中,我们主要使用的是Dart的File类进行文件操作,因为fs_service通常用于更复杂的文件服务场景(比如跨平台文件访问的统一接口)。如果你仅仅是在Flutter应用中进行基本的文件读写,直接使用dart:io库中的File类通常是足够的。
  3. 文件读写
    • 保存文件:点击“Save File”按钮时,会在应用的文档目录中创建一个名为example.txt的文件(如果文件已存在则覆盖),并将文本框中的内容写入文件。
    • 读取文件:点击“Read File”按钮时,会读取example.txt文件的内容,并将其显示在文本框中。

注意:在实际应用中,如果你确实需要使用fs_service插件提供的特定功能(比如跨平台文件访问的统一接口),你可能需要参考fs_service的官方文档,因为直接使用dart:io库可能无法覆盖所有场景。在这个示例中,为了简单起见,我们使用了dart:io库中的File类。

回到顶部