Flutter文件服务插件fs_service的使用
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 服务账户。所需步骤如下:
- 创建 Firestore 项目的服务账户。
- 下载用于访问该账户的 JSON 证书文件。
- 设置 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.json
和 col-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-doc
、add-doc
和 del-doc
命令,但设计用于处理集合。
更多详细信息
有关工具和每个命令的详细信息,请运行以下命令:
dart run fs_service --help
dart run fs_service help add-doc
更多关于Flutter文件服务插件fs_service的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于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'),
),
],
),
),
),
);
}
}
解释
- 依赖管理:在
pubspec.yaml
文件中添加fs_service
依赖。 - 文件系统服务:使用
FileSystemService
类,但实际上在这个例子中,我们主要使用的是Dart的File
类进行文件操作,因为fs_service
通常用于更复杂的文件服务场景(比如跨平台文件访问的统一接口)。如果你仅仅是在Flutter应用中进行基本的文件读写,直接使用dart:io
库中的File
类通常是足够的。 - 文件读写:
- 保存文件:点击“Save File”按钮时,会在应用的文档目录中创建一个名为
example.txt
的文件(如果文件已存在则覆盖),并将文本框中的内容写入文件。 - 读取文件:点击“Read File”按钮时,会读取
example.txt
文件的内容,并将其显示在文本框中。
- 保存文件:点击“Save File”按钮时,会在应用的文档目录中创建一个名为
注意:在实际应用中,如果你确实需要使用fs_service
插件提供的特定功能(比如跨平台文件访问的统一接口),你可能需要参考fs_service
的官方文档,因为直接使用dart:io
库可能无法覆盖所有场景。在这个示例中,为了简单起见,我们使用了dart:io
库中的File
类。