使用Firestore和GetX状态管理MVC模式在Flutter Web中进行角色库授权

问题描述

我将要开发企业级Flutter Web解决方案。因此,我决定遵循适当的状态管理包而非SetState。这是我的第一个Flutter Web应用程序,也是我第一次尝试使用GetX

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

错误明确指出错误状态:无法在DocumentSnapshotPlatform上获取不存在的字段” 。但是,如何确定确切原因?有人可以帮助我了解我在哪里犯了错误

错误

[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 usermodel{
  String id;
  String name;
  String role;

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

  usermodel.fromDocumentSnapshot(DocumentSnapshot doc){
    id = doc["id"];
    name = doc["name"];
    name = doc["role"];
  }

}

用户控制器

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();
  }
}

数据库服务

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",);
    });
      return usermodel.fromDocumentSnapshot(doc);
  }
}

Firestore收藏

enter image description here

解决方法

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

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

  UserModel.fromDocumentSnapshot(DocumentSnapshot doc) {
    id = doc.data().containsKey("id") ? doc.data()["id"] : '';
    name = doc.data().containsKey("name") ? doc.data()["name"] : '';
    role = doc.data().containsKey("role") ? doc.data()["role"] : '';
  }
}
,

我最近有同样的错误。我最近升级了几个Firebase软件包(cloud_firestore:^ 0.14.1 + 3,firebase_auth:^ 0.18.1 + 2,firebase_dynamic_links:^ 0.6.0 + 2,firebase_storage:^ 4.0.1)。之后,清理所有不推荐使用的方法,等等。我开始得到相同的信息:“无法在不存在的DocumentSnapshotPlatform上获取字段”。

我最终发现,如果我将所有引用从doc [“ fooBar”]更改为doc.data()[“ fooBar”],则可以解决此问题。尝试将代码更改为以下内容:

useDispatch

进一步阅读(https://pub.dev/packages/cloud_firestore/changelog)之后,我发现了有关0.14.0版本的DocumentSnapshots的以下注释:

“ DocumentSnapshot:

BREAKING:现在,获取数据获取器现在是data()方法。 ... “