我很喜欢这篇 CodeLab,我自己认为,如果这篇的内容看得懂那 Provider
基本上都会了。
如果想要看这篇的成品什麽样子,欢迎去 官方 CodeLab 看。
接续 【第十四天 - Flutter 官方 CodeLab Get-To-Know 活动报名教学(上)】,直接进入主题介绍方法。
在使用 Firebase 的时候都需要初始化。
await Firebase.initializeApp();
这边是用来查看有几个人参加报名的,不需要判断有无登入,都需要有参与者的人数。
可以看到这里,他去找寻 collection == attendees
并找寻底下的 attending 栏位 == true
,并进行即时监听资料。可以看到这里,他去找寻 collection == attendees
并找寻底下的 attending 栏位 == true
,并进行即时监听资料。
FirebaseFirestore.instance
.collection('attendees')
.where('attending', isEqualTo: true)
.snapshots()
.listen((snapshot) {
_attendees = snapshot.docs.length;
notifyListeners();
});
这边是先判断使用者是否有登入
未登入
Subscription
collection == guestbook
,并且照着 timestamp 由大到小排序
,并读取每一个 document 的资料
)FirebaseFirestore.instance.collection('attendees').doc(user.uid)
,是表示他要去取得 attendees
的资料,并且 doc 的 id == user.uid(现在使用者 的 uid)
。 // 监听使用者使否有登入的资讯
FirebaseAuth.instance.userChanges().listen((user) {
// 更改後,使用者从无登入 -> 已经登入的状态
if (user != null) {
_loginState = ApplicationLoginState.loggedIn;
// StreamSubscription 监听资讯
_guestBookSubscription = FirebaseFirestore.instance
.collection('guestbook')
.orderBy('timestamp', descending: true)
.snapshots()
.listen((snapshot) {
// 先清空资料
_guestBookMessages = [];
snapshot.docs.forEach((document) {
_guestBookMessages.add(
GuestBookMessage(
name: document.data()['name'].toString(),
message: document.data()['text'].toString(),
),
);
});
// 资料变动完後, rebuild 画面
notifyListeners();
});
// 监听 attending 参加人数的资料
_attendingSubscription = FirebaseFirestore.instance
.collection('attendees')
.doc(user.uid)
.snapshots()
.listen((snapshot) {
if (snapshot.data() != null) {
if (snapshot['attending']==true) {
_attending = Attending.yes;
} else {
_attending = Attending.no;
}
} else {
_attending = Attending.unknown;
}
notifyListeners();
});
} else {
// 关闭监听器
_loginState = ApplicationLoginState.loggedOut;
_guestBookMessages = [];
_guestBookSubscription?.cancel();
_attendingSubscription?.cancel(); // new
}
notifyListeners();
});
```
# 更新参与者状况
这边会去存入 `collection == attendees` 且 `document id == currentUser.uid`。
存入资料都必须像这样,是一个 `map` 的型态。
```dart
/// 更新 firebase user 的参加状态。
/// 这边更新後会触发 firebase 的 userChanges().listen,然後信行 attending 的更新
set attending(Attending attending) {
final userDoc = FirebaseFirestore.instance
.collection('attendees')
.doc(FirebaseAuth.instance.currentUser!.uid);
if (attending == Attending.yes) {
var map = {'attending': true};
userDoc.set(map);
} else {
var map = {'attending': false};
userDoc.set(map);
}
}
这边会去存入 `collection == guestbook`,这边没有指定 `document` 的名称,因此 `firebase` 会随机产生。
存入资料都必须像这样,是一个 map 的型态。
/// 更新 firebase message 的留言状态。
/// 这边更新後会触发 firebase 的 userChanges().listen,然後信行 attending 的更新
Future<DocumentReference> addMessageToGuestBook(String message) {
if (_loginState != ApplicationLoginState.loggedIn) {
throw Exception('Must be logged in');
}
var map = {
'text': message,
'timestamp': DateTime.now().millisecondsSinceEpoch,
'name': FirebaseAuth.instance.currentUser!.displayName,
'userId': FirebaseAuth.instance.currentUser!.uid,
};
return FirebaseFirestore.instance.collection('guestbook').add(map);
}
他会返回可用於登录给定的登录方法列表,用户(由其主要电子邮件地址标识)。当您支持多种身份验证机制时,此方法很有用。如果找不到用户,则返回一个空的 List
。如果电子邮件地址无效则抛出 FirebaseAuthException
不合规电邮。
FirebaseAuth.instance.fetchSignInMethodsForEmail(email)
提供 eamil 的登入方式
FirebaseAuth.instance.signInWithEmailAndPassword
注册
FirebaseAuth.instance
.createUserWithEmailAndPassword(email: email, password: password);
FirebaseAuth.instance.signOut();
Cosumer
,他类似一个 View
的控制器,他有 Cosumer2
、Cosumer3
等等...,builder
里面第一个参数是 contex
t,第二个则是 model(ApplicationProvider 的 model)
,第三个则是 child
。
Consumer4 的范例
Consumer4<changeNotifier1, changeNotifier2, changeNotifier3, changeNotifier4>(
builder: (context, changeNotifier1, changeNotifier2, changeNotifier3, changeNotifier4, child) {
// return your widget
}
)
这边的话,累是一个 View
的中转站,从 ApplicationProvider
取得现在登入的状态,和方法,在 Consumer
中转站传递给自定义的 Authentication
元件,让逻辑和画面分离。并使用 callBack
的方式,让 ApplicationProvider
,Firebase 里面的 exception
可以显示在画面上面。
Consumer<ApplicationProvider>(
builder: (context, appState, _) {
return Authentication(
email: appState.email,
loginState: appState.loginState,
startLoginFlow: appState.startLoginFlow,
// 把逻辑写在 provider 里面。然後当 Widget 里面触发资料後
verifyEmail: appState.verifyEmail,
signInWithEmailAndPassword: appState.signInWithEmailAndPassword,
cancelRegistration: appState.cancelRegistration,
registerAccount: appState.registerAccount,
signOut: appState.signOut,
)
;
}
),
这篇虽然很长,但是只要看懂 provider
、Authentication
元件、CallBack
,整篇大约就会一目了然。
初接触 Firebase
的朋友,可能就要了解一下要怎麽连接 Firebase
,还有 FireStore
怎麽使用,collection
、document
、userID
、还有一些即时更新的 listener
,需要去熟悉他,希望大家可以在 Flutter 上有所成长~~
<<: [第14天]理财达人Mx. Ada-盘中零股交易(Intraday Odd Order)
今天大概会聊到的范围 Constraint Layout in Compose 上一篇提到,有 R...
游戏示意 swift 版本 kotlin 版本 swift - 改写小鸡动画 原本画面是这样 下一步...
今天要介绍如何安装 Kafka 方法一. 利用 Docker 安装 Kafka 安装 Docker-...
前言 Hi, 我是鱼板伯爵接着就是来验证登入状态,如果已经登入就跳转到首页否则就在登入画面,看完我这...
摧毁阶段 这个阶段负责元件的移除,适合用来移除所有的事件监听以及任何会造成记忆体泄漏(memory ...