簡體   English   中英

GetX Controller - 等待 firebase RTDB stream 被填充

[英]GetX Controller - Wait for firebase RTDB stream to be populated

我是 GetX 的新手,想了解一些正確的概念。 這是我使用Firebase Realtime Database獲取當前用戶所在組的過程:

  1. 創建一個 AuthController 以獲取當前用戶 ID(完美運行)

     class AuthController extends GetxController { FirebaseAuth auth = FirebaseAuth.instance; Rx<User?> firebaseUser = Rx<User?>(FirebaseAuth.instance.currentUser); User? get user => firebaseUser.value; @override void onInit() { firebaseUser.bindStream(auth.authStateChanges()); super.onInit(); } } ```
  2. 創建一個 UserController 以獲取用戶擁有的組的 ID(部分工作)

class FrediUserController extends GetxController {
  Rx<List<String>> groupIdList = Rx<List<String>>([]);

  List<String> get groupIds => groupIdList.value;

  @override
  void onInit() {
    User? user = Get.find<AuthController>().user;

    if (user != null) {
      String uid = user.uid;
      groupIdList.bindStream(DatabaseManager().userGroupIdsStream(uid));
      print(groupIds); //prints [] when it should be populated
    }
    super.onInit();
  }
}
  1. 創建一個 GroupsController 以從這些 id 中獲取組(不工作)-> 依賴於 UserController 已填充了 id。
class FrediGroupController extends GetxController {
  Rx<List<FrediUserGroup>> groupList = Rx<List<FrediUserGroup>>([]);

  List<FrediUserGroup> get groups => groupList.value;

  void bindStream() {}

  @override
  void onInit() {
    final c = Get.find<FrediUserController>();
    List<String> groupIds = c.groupIds;
    print(groupIds); //prints [], when it should have ids
    groupList.bindStream(DatabaseManager().groupsStream(groupIds)); //won't load anything without id's

    super.onInit();
  }
}

觀察

  • 在main.dart文件中依次調用get.put:
  Get.put(AuthController());
  Get.put(FrediUserController());
  Get.put(FrediGroupController());
  • 在我的 HomePage() Stateful Widget 中,如果我調用UserController ,數據會正確加載:
    GetX<FrediUserController>(
                  builder: (controller) {
                    List<String> groups = controller.groupIds;
                     print(groups); //PRINTS the list of correct ids. THE DATA LOADS.
                    return Expanded(
                      child: ListView.builder(
                        shrinkWrap: true,
                        itemCount: groups.length,
                        itemBuilder: (context, index) {
        return Text('${groups[index]}', 
               style: TextStyle(color: Colors.white));
                                                        },),); },),

問題

就好像 ZF7B44CFFAFD5C52223D5498196C8A2E7BZ 需要一些時間來填充,但UserController不會等待它並將 controller 初始化為空,但在一段時間后它會填充(沒有及時將數據傳遞給GroupController

我怎樣才能解決這個問題? 我嘗試過異步,但運氣不佳。

我想要的行為:

  • 流可能/可能尚未准備好,因此它可以初始化為空或不初始化。
  • 但是,如果 ZF7B44CFFAFD5C52223D5498196C8A2E7BZ 到達,一切都應該更新,包括初始化依賴UserController的控制器,如GroupController
  • 因此,使用新值重建 UI。

謝謝你!

您只需在 onInit 方法中獲取用戶一次。 您沒有得到用戶更改。 要獲得所有更改,您必須使用“ever”function。 例如,“firebaseUser.value”就像是當前可觀察到的 firebaseUser 的照片。

如果我可以提出建議,請不要將控制器與提供者混淆。 將 Firebase 視為提供者,將 controller 視為 UI 和提供者之間的中間點。 您可以在 controller 收聽 Firebase 流以更新 UI 並從您的 Firebase 提供程序中的 UI 更改參數進行調用。 將您的關注點分成兩個不同的類,您可能會有更好的設計。

您可以添加兩件事:

  1. Future Builder 在從 RTDB 獲取數據時顯示一些加載屏幕
  2. function
class AuthController extends GetxController {
late Rx<User?> firebaseuser;

  @override
  void onReady() {
    super.onReady();
    firebaseuser = Rx<User?>(FirebaseAuth.instance.currentUser);
    firebaseuser.bindStream(FirebaseAuth.instance.idTokenChanges());
    ever(firebaseuser, _setInitialScreen);
  }

  _setInitialScreen(User? user) {

    if (user != null) {
      //User Logged IN
      
    } else {
      //User Logged out
      
    }
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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