Flutter 使用Firestore和GetX状态管理(MVC模式)在Flatter Web中基于角色的授权

Flutter 使用Firestore和GetX状态管理(MVC模式)在Flatter Web中基于角色的授权,flutter,google-cloud-firestore,state-management,role-base-authorization,flutter-get,Flutter,Google Cloud Firestore,State Management,Role Base Authorization,Flutter Get,我将开发一个企业级的颤振Web解决方案。所以我决定遵循一个适当的状态管理包,而不是SetState。这是我的第一个Flitter web应用程序,也是我第一次尝试使用它 我将使用Firestore实现角色库授权。一旦用户登录到系统,如果他是管理员,他将被重定向到管理页面,否则重定向到用户页面。登录功能工作正常。但我无法从Firestore获得该角色。我解释了所有这些,因为我想知道以下错误的解决方案,并知道我是否正确地执行了状态管理 错误清楚地表明“错误状态:无法在DocumentSnapshot

我将开发一个企业级的颤振Web解决方案。所以我决定遵循一个适当的状态管理包,而不是SetState。这是我的第一个Flitter web应用程序,也是我第一次尝试使用它

我将使用Firestore实现角色库授权。一旦用户登录到系统,如果他是管理员,他将被重定向到管理页面,否则重定向到用户页面。登录功能工作正常。但我无法从Firestore获得该角色。我解释了所有这些,因为我想知道以下错误的解决方案,并知道我是否正确地执行了状态管理

错误清楚地表明“错误状态:无法在DocumentSnapshot平台上获取不存在的字段”。但我怎样才能确定确切的原因呢?有人可以帮助我理解我在哪里犯了错误

错误:

[GETX] "AuthController" has been initialized
[GETX] "UserController" has been initialized
[GETX] "GetMaterialController" has been initialized
[GETX] GOING TO ROUTE /login-page
LoginSuccess
Error: Bad state: cannot get a field on a DocumentSnapshotPlatform which does not exist
    at Object.throw_ [as throw] (http://localhost:5000/dart_sdk.js:4328:11)
    at platform_interface_document_snapshot.DocumentSnapshotPlatform.new.get (http://localhost:5000/packages/cloud_firestore_platform_interface/src/platform_interface/platform_interface_write_batch.dart.lib.js:652:19)
    at cloud_firestore.DocumentSnapshot.__.get (http://localhost:5000/packages/cloud_firestore/cloud_firestore.dart.lib.js:697:73)
    at cloud_firestore.DocumentSnapshot.__._get (http://localhost:5000/packages/cloud_firestore/cloud_firestore.dart.lib.js:700:19)
    at new user_model.UserModel.fromDocumentSnapshot (http://localhost:5000/packages/equipment_management_system/models/user_model.dart.lib.js:47:32)
    at database.Database.new.getUser (http://localhost:5000/packages/equipment_management_system/views/pages/login_page.dart.lib.js:3180:16)
    at getUser.next (<anonymous>)
    at http://localhost:5000/dart_sdk.js:37593:33
    at _RootZone.runUnary (http://localhost:5000/dart_sdk.js:37447:58)
    at _FutureListener.thenAwait.handleValue (http://localhost:5000/dart_sdk.js:32424:29)
    at handleValueCallback (http://localhost:5000/dart_sdk.js:32971:49)
    at Function._propagateToListeners (http://localhost:5000/dart_sdk.js:33009:17)
    at _Future.new.[_completeWithValue] (http://localhost:5000/dart_sdk.js:32852:23)
    at async._AsyncCallbackEntry.new.callback (http://localhost:5000/dart_sdk.js:32874:35)
    at Object._microtaskLoop (http://localhost:5000/dart_sdk.js:37708:13)
    at _startMicrotaskLoop (http://localhost:5000/dart_sdk.js:37714:13)
    at http://localhost:5000/dart_sdk.js:33226:9
  handleAuthChanged(isLoggedIn) async {
    final UserController userController = Get.put<UserController>(UserController());
    if (isLoggedIn == false) {
      Get.offAllNamed(LoginPageRoute);
    } else {
      print("LoginSuccess");
      userController.user = await Database().getUser(user.value.uid).then((value){
        print(userController.user.id);
        if(userController.user.role == "Admin"){
          Get.offAllNamed(AdminHomePageRoute);
        }else{
          Get.offAllNamed(UserHomePageRoute);
        }
        return;
      });
    }
  }
用户控制器

class UserController extends GetxController{
  Rx<UserModel> _userModel = UserModel().obs;
  UserModel get user => _userModel.value;
  set user(UserModel value) => this._userModel.value = value;
  void clear(){
    _userModel.value = UserModel();
  }
}
类UserController扩展了GetxController{ Rx_userModel=userModel().obs; UserModel get user=>\u UserModel.value; 设置用户(UserModel值)=>this.\u UserModel.value=value; 无效清除(){ _userModel.value=userModel(); } } 数据库服务

class Database{
  final FirebaseFirestore _firebaseFirestore = FirebaseFirestore.instance;

  Future<bool> createNewUser(UserModel user) async {
    await _firebaseFirestore.collection("users").doc(user.id).set({
      "name" : user.name,
      "role" : user.role,
    }).catchError((onError){
      Get.snackbar(
        "", "",
        titleText: Text("An error occurred while connecting to the database", style: TextStyle(fontFamily: "Poppins", fontWeight: FontWeight.bold, fontSize: 16)),
        messageText: Text(onError.message, style: TextStyle(fontFamily: "Poppins")),
        colorText: primaryColor,
        backgroundColor: Colors.white.withOpacity(0.5),
        margin: EdgeInsets.only(top: 20, left: 20, right: 20),
        barBlur: 10,
      );
      return false;
    });
    return true;
  }

  Future<UserModel> getUser(String uid) async{
    DocumentSnapshot doc = await _firebaseFirestore.collection("users").doc(uid).get().catchError((onError){
      Get.snackbar(
        "", "",
        titleText: Text("An error occurred while retrieving data", style: TextStyle(fontFamily: "Poppins", fontWeight: FontWeight.bold, fontSize: 16)),
        messageText: Text(onError.message, style: TextStyle(fontFamily: "Poppins")),
        colorText: primaryColor,
        backgroundColor: Colors.white.withOpacity(0.5),
        margin: EdgeInsets.only(top: 20, left: 20, right: 20),
        barBlur: 10,
      );
    });
      return UserModel.fromDocumentSnapshot(doc);
  }
}
类数据库{
最终FirebaseFirestore _FirebaseFirestore=FirebaseFirestore.instance;
未来createNewUser(UserModel用户)异步{
wait_firebaseFirestore.collection(“users”).doc(user.id).set({
“name”:user.name,
“角色”:user.role,
}).catchError((onError){
快去吃零食吧(
"", "",
titleText:Text(“连接到数据库时出错”,样式:TextStyle(fontFamily:“Poppins”,fontWeight:fontWeight.bold,fontSize:16)),
messageText:Text(onError.message,style:TextStyle(fontFamily:“Poppins”),
colorText:primaryColor,
背景颜色:颜色。白色。不透明度(0.5),
页边距:仅限边集(顶部:20,左侧:20,右侧:20),
巴布卢:10,
);
返回false;
});
返回true;
}
未来getUser(字符串uid)异步{
DocumentSnapshot doc=wait_firebaseFirestore.collection(“users”).doc(uid.get().catchError((onError){
快去吃零食吧(
"", "",
titleText:Text(“检索数据时出错”,样式:TextStyle(fontFamily:“Poppins”,fontWeight:fontWeight.bold,fontSize:16)),
messageText:Text(onError.message,style:TextStyle(fontFamily:“Poppins”),
colorText:primaryColor,
背景颜色:颜色。白色。不透明度(0.5),
页边距:仅限边集(顶部:20,左侧:20,右侧:20),
巴布卢:10,
);
});
返回UserModel.fromDocumentSnapshot(doc);
}
}
Firestore系列


我最近也犯了同样的错误。我最近升级了几个Firebase软件包(cloud\u firestore:^0.14.1+3,Firebase\u auth:^0.18.1+2,Firebase\u动态链接:^0.6.0+2,Firebase\u存储:^4.0.1)。在清理了所有不推荐的方法之后,我开始得到同样的“无法在DocumentSnapshot平台上获取不存在的字段”

我最终发现,如果我将所有引用从doc[“fooBar”]更改为doc.data()[“fooBar”],那么问题就解决了。尝试将代码更改为以下格式:

class UserModel{
    String id;
    String name;
    String role;

    UserModel({id, name, email, role});

    UserModel.fromDocumentSnapshot(DocumentSnapshot doc){
        id = doc.data()["id"] // previously doc["id"];
        name = doc.data()["name"] // previously doc["name"];
        name = doc.data()["role"] // previously doc["role"];
    }
}
在进一步阅读()之后,我发现了以下关于0.14.0版的DocumentSnapshot的注释^

“文档快照:

中断:get data getter现在是data()方法。 ... "

class UserModel{
    String id;
    String name;
    String role;

    UserModel({id, name, email, role});

    UserModel.fromDocumentSnapshot(DocumentSnapshot doc){
        id = doc.data()["id"] // previously doc["id"];
        name = doc.data()["name"] // previously doc["name"];
        name = doc.data()["role"] // previously doc["role"];
    }
}