簡體   English   中英

如何在 Riverpod 中管理 Firebase 身份驗證?

[英]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是一個有狀態的小部件,其中包含文本字段、控制器等。在這個文件中,我在userEmailuserPassword中有用戶 email 和密碼,現在如何使用它來登錄用戶? Firebase Auth的官方文檔使用以下代碼:

UserCredential userCredential = await FirebaseAuth.instance.signInWithEmailAndPassword(
    email: "barry.allen@example.com",
    password: "SuperSecretPassword!"
);

我也可以這樣做,但這不會涉及 Riverpod。 我需要訪問包含firebaseAuthProviderFirebaseAuth.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM