[英]How to manage Firebase Authentication in Riverpod?
我有一個firebase_providers.dart
文件,如下所示:
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:firebase_auth/firebase_auth.dart';
final firebaseAuthProvider = Provider((ref) => FirebaseAuth.instance);
final authStateChangesProvider = StreamProvider.autoDispose<User?>((ref) {
return ref.watch(firebaseAuthProvider).authStateChanges();
});
它創建了 2 個簡單的提供程序 - 一個用於 Firebase Auth 實例,另一個用於獲取當前用戶狀態。 我在我的主頁上使用它,如下所示:
class NavigationManager extends HookWidget {
@override
Widget build(BuildContext context) {
final user = useProvider(authStateChangesProvider);
return user.when(
loading: () => CircularProgressIndicator(),
error: (error, stack) => Text('Error occured'),
data: (user) {
if (user == null) return LoginPage();
return Dashboard();
},
);
}
}
這是我根據用戶身份驗證狀態更改頁面的基本設置。
LoginPage
是一個有狀態的小部件,其中包含文本字段、控制器等。在這個文件中,我在userEmail
和userPassword
中有用戶 email 和密碼,現在如何使用它來登錄用戶? Firebase Auth的官方文檔使用以下代碼:
UserCredential userCredential = await FirebaseAuth.instance.signInWithEmailAndPassword(
email: "barry.allen@example.com",
password: "SuperSecretPassword!"
);
我也可以這樣做,但這不會涉及 Riverpod。 我需要訪問包含firebaseAuthProvider
的FirebaseAuth.instance
。 要訪問此提供程序,我需要在HookWidget
內才能使用useProvider
,但這意味着將 ui 與邏輯混淆。 我想將邏輯分開保存在提供者所在的同一個文件中,即firebase_providers.dart
我也想過做這樣的事情 - 將LoginPage
有狀態小部件轉換為 HookWidget,然后訪問firebaseAuthProvider
並使用它來調用 function 中的標志,該標志可以駐留在firebase_providers.dart
中,但是我將如何管理其表單和文本字段我首先創建了有狀態的小部件?
那么使用 Riverpod 管理和調用所有這些身份驗證功能(如登錄、注冊等)的方法是什么?
標准方法是創建一個接受ScopedReader
作為參數的服務 class。
例如:
class AuthService {
const AuthService(this._read);
final Reader _read;
static final provider = Provider((ref) => AuthService(ref.read));
Future<void> emailSignIn(String email, String password) async {
final auth = _read(firebaseAuthProvider);
final credential = await auth.signInWithEmailAndPassword(email: email, password: password);
// etc.
}
}
然后在您的登錄頁面中:
class LoginPage extends HookWidget {
const LoginPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () async => context.read(AuthService.provider).emailSignIn(
'barry.allen@example.com',
'SuperSecretPassword!',
),
child: Text('Login'),
);
}
}
相同的模式可以應用於使用 Firestore 或其他數據提供程序的存儲庫類。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.