介绍
在构建我的应用程序时,我发现了100种来自Firestorm数据库数据的方法,尤其是Internet中仍然有一些过时的信息。
在这篇文章中,我希望给出最清晰的方法来实现所有CRUD操作,尤其
我假设您已经设置了Firebase并熟悉Flutter的语法。
设置模型
首先,我建议您在Firestone内部创建该集合和“演示”文档,以掌握您将如何创建的模型。
就像您可以看到IV创建了收集动物一样,其中有几个领域。一个特别的字段是“ ID”字段,我个人喜欢使用Uniq ID Firebase自动创建每个文档,从而为其生成,这有助于避免发生冲突。我创建字段“ ID”,因此访问ID非常容易,还有其他方法可以通过调用数据库中的文档ID来访问它,但是我们不会在此处访问。有时,给予其他类型的ID是可取的,例如,当我创建一个“用户”集合时,我更喜欢将ID作为电子邮件作为电子邮件,这有助于搜索用户,尤其是如果您以后将其分组在其他集合中。 /p>
回到我们的收藏“动物”,现在我知道我的数据库中的对象看起来像什么,我会在flutter中创建模型。
为该井创建一个新文件animals_model.dart
。
内部井创建一个用于动物的课程,并列出创建“动物”对象的要求:
class Animal {
String id; //id of the document inside firestore's db
String name; // name of the animal
int nubmer_of_legs; // nubmer of legs the animals has
DateTime creation_date; // when the document was added tot he db
Animal ({
this.id = '',
required this.name,
required this.nubmer_of_legs,
required this.creation_date,
});}
此类将保存对象的模型。该模型将定义将保存到Firestore的所有必要数据。
因此,现在我们已经可以创建一个类型的“动物”对象,但是我们需要将其添加到数据库中。为此,将成为createAnimalDoc
方法,但是在此之前,我们需要可以将对象数据转换为JSON并从JSON转换。
Map<String, dynamic> toJson() => {
'id': id,
'name': name,
'nubmer_of_legs': nubmer_of_legs,
'creation_date': creation_date,
};
static Animal fromJson(Map<String, dynamic> json) => Animal(
id: json['id'],
name: json['name'],
nubmer_of_legs: json['nubmer_of_legs'],
creation_date: (json['creation_date'] as Timestamp).toDate(), // import 'package:cloud_firestore/cloud_firestore.dart';
);
toJson()
获取动物对象数据并将其放入JSON格式,以便Firestone可以理解,fromJson
映射所有字段,并获取数据并将其放入模型构建器变量中,以便我们可以在代码中访问它。 p>
创建
在所有这些设置之后
要在firebase中创建一个新文档,我们只需创建createAnimalDoc
的方法,如以下内容:
Future createAnimalDoc(String name, int nubmer_of_legs, DateTime creation_date) async {
final newDocAnimal = FirebaseFirestore.instance.collection('groups').doc();
final animal = Animal(
name: name,
id: newDocAnimal.id,
nubmer_of_legs: nubmer_of_legs,
creation_date: creation_date);
await newDocAnimal.set(animal.toJson());
}
在此处,我们将所有变量都放入函数中,但是如果您使用控制器,也可以在此处列出它们,如果您使用了某种形式。
如果我要创建一个带有特定ID的新文档,则将其输入...doc('ENTER ID');
阅读
在我看来,阅读是用Flutter+Firestore的Crud操作中最通用的。这是因为您可能会从数据库中请求所有不同的数据。显然,您不会调用您拥有的所有数据,而只能与您的用例相关。列出了一些示例,以及如何在代码中求解/处理它们。
在开始之前,有一件事要记住,要在flutter中显示该数据,必须使用窗口小部件FutureBuilder()
或StreamBuilder()
。本质上,您需要请求数据并等待到达,这些小部件可以做到这一点,同时使您能够检查数据是否存在,是否存在错误或是否到达数据以及该如何处理。 br>
FutureBuilder()
和StreamBuilder()
之间的区别在于,FutureBuilder()
在调用小部件时一次要求数据快照,等待它然后显示它。它的问题是,如果要更改数据,它才会知道它,直到再次调用(如果您刷新页面或其他内容)。另一方面,StreamBuilder()
请求流并连续将信息发送到页面。因此,如果数据在数据库中更改,则该页面也将在页面内部进行更新。
您需要的东西可以判断什么。如果一个快照就足够了,并且您不希望信息更改,则将FutureBuilder()
用作应用程序更轻,并更少对数据库进行调用。如果需要实时更新信息,那么StreamBuilder()
是您的家伙。
让我们看看如何使用在我们的代码中,在此示例中,我使用StreamBuidler()
:
首先创建一个空页面
import 'package:flutter/material.dart';
class AnimalsPage extends StatefulWidget {
const AnimalsPage({super.key});
@override
State<AnimalsPage> createState() => _AnimalsPageState();
}
class _AnimalsPageState extends State<AnimalsPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(),
);
}
}
现在生病的呼叫方法,将“管道”变成firestore:
Stream<List<Animal>> fetchAnimals() {
return FirebaseFirestore.instance
.collection('animals')
.snapshots()
.map((snapshot) => snapshot.docs
.map((doc) => Animal.fromJson(doc.data()))
.toList());
}
现在生病了StreamBuilder()
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: StreamBuilder<List<Animal>>(
stream: fetchAnimals(), // feed our stream to the stream builder
builder: (context, snapshot) {
if (snapshot.hasData) {
final animals = snapshot.data!;
return ListView.builder(
itemCount: animals.length,
itemBuilder: (context, index) {
return animalTile(animals[index]);
}
);
} else if (snapshot.hasError) {
return Text('Something went wrong!');
} else {
return Text('Something went wrong!');
}
},
),
),
);
}
您可以查看是否检查快照的数据是否存在,这对于调试不起作用。
最后,我们需要构建将显示信息的瓷砖。我喜欢在同一文件中使用一个单独的小部件进行操作:
Widget animalTile(Animal animal) => ListTile(
title: Container(
height: 50,
width: 50,
child: Text(animal.name),
),
);
现在我们可以从数据库中请求有关收集动物的任何信息。
好吧,我们如何使用futureBuilder()
做到这一点?本质上相同的方式:
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: FutureBuilder<List<Animal>>(
future: fetchAnimals(),
builder: (context, snapshot) {
if (snapshot.hasData) {
final animals = snapshot.data!;
return ListView.builder(
itemCount: animals.length,
itemBuilder: (context, index) {
return animalTile(animals[index]);
});
} else if (snapshot.hasError) {
return Text('Something went wrong!');
} else {
return Text('Something went wrong!');
}
},
),
),
);
}
Future<List<Animal>> fetchAnimals() async {
var collectionSnapshot =
await FirebaseFirestore.instance.collection('animals').get();
return collectionSnapshot.docs.map((doc) => Animal.fromJson(doc.data())).toList();
}
方法fetchAnimals()
需要异步等待快照从数据库到达。
特殊情况:
-
当您想从整个集合中获取特定文档时,您可以调用.collection.doc(document_id)
-
如果要搜索具有特定字段的文档,则可以使用
.where()
实现此目的,请在official documentaion中进行更多信息。
更新
这很简单,您可以在文档中获得,然后只需致电.update()
示例:
FirebaseFirestore.instance.collection('animals').doc('DOC_ID').update({
'FIELD1': 'NEW_DATA',
'FIELD2': 'NEW_DATA',
});
删除
与更新相同,您可以在文档中获得,然后只需致电.delete()
示例:
FirebaseFirestore.instance.collection('animals').doc('DOC_ID').delete();
希望这能提供更多有关该主题的最新信息,请记住还有其他方法可以通过Firestore处理CRUD功能,这只是我的方式。
-t