3
votes

Obtention et stockage des données utilisateur après la connexion / inscription

Je souhaite charger les informations de profil utilisateur à partir de Firestore après la connexion de l'utilisateur et je souhaite que ces données soient disponibles pour l'ensemble de l'application lorsque les données sont connectées. Je prévois de faire la dernière partie en utilisant des widgets hérités dans Flutter. Je peux charger correctement les données de Firestore et obtenir toutes les données, mais la page d'accueil n'attend pas le chargement des données avant de continuer, donc j'obtiens des erreurs. Il appelle la méthode, puis ignore la partie d'attente de la méthode et continue, donc j'obtiens des erreurs, puis après les erreurs, j'obtiens les messages de données que les données ont chargés.

J'ai essayé plusieurs choses. J'ai tout mon code de gestion des utilisateurs (connexion, inscription, ...) dans un fichier et j'ai écrit une méthode getuserProfie () dans ce fichier. La méthode obtient toutes les données, remplit un modèle utilisateur avec les données et renvoie ce modèle. Voir le code ci-dessous.

      @override
      void initState() {
      Usermode user = UserManagement().getUserProfile(); //Calling the method
      super.initState();
      }

J'appelle ensuite cette méthode dans ma page d'accueil comme suit

 getUserProfile() async {
    UserModel theUser;
    await FirebaseAuth.instance.currentUser().then((user) {
     Firestore.instance
      .collection('/users')
      .where('uid', isEqualTo: user.uid)
      .snapshots()
      .listen((data) {
    print('getting data');
    theUser = new UserModel(user.uid, data.documents[0]['email'],);

    print('got data');
    print(theUser.email);
    return theUser;
  });
}).catchError((e) {
  print("there was an error");
  print(e);
});
}

Cela appelle la méthode très bien et obtient tout les données mais le programme n'attend pas que les données soient obtenues pour continuer. J'ai essayé de déplacer le code qui récupère les données dans la méthode initState () et d'appeler super.initState () quand j'étais sûr qu'il y avait une valeur mais cela n'a pas fonctionné. J'ai également essayé d'appeler getUserProfile () avant d'appeler super.initstate () mais cela n'a pas fonctionné.

J'ai essayé d'ajouter async à l'en-tête initState () mais flutter n'aime pas ça. Je peux obtenir les données de Firebase très bien, mais faire attendre le programme jusqu'à ce que les données soient obtenues est le problème que j'ai. On dirait que l'utilisation de await et async ne fonctionne pas. Avez-vous d'autres suggestions pour vous assurer que les données sont chargées avant de continuer? J'ai pensé à utiliser FutureBuilder mais je ne sais pas comment cela fonctionnerait dans ce cas.


1 commentaires

Vous pouvez appeler la fonction async à partir de la méthode initState et lors de l'appel de méthode setState à partir de la méthode async et vous pouvez vérifier la valeur de l'objet dans la méthode de construction du widget


3 Réponses :


0
votes

Puisque getUserProfile est async , vous devrez utiliser await lors de son appel:

@override
void initState() async {
  Usermode user = await UserManagement().getUserProfile();
  super.initState();
}

p>


2 commentaires

Cela n'a pas fonctionné. J'ai eu une erreur comme celle-ci: thepage.initState () a renvoyé un Future. flutter: State.initState () doit être une méthode void sans mot clé async . flutter: Plutôt que d'attendre un travail asynchrone directement dans initState,


Ah ok. Et c'est ce que vous avez essayé de faire je suppose. J'espère que quelqu'un d'autre connaîtra une solution dans ce cas.



2
votes

initState () ne peut pas être une fonction asynchrone .

Ce que vous pouvez essayer est - Déplacez Usermode user = wait UserManagement (). getUserProfile (); à une nouvelle fonction async .

@override
  Widget build(BuildContext context) {
    if (user != null) {
      return ProfilePage();
    } else {
      return CircularProgressIndicator();
    }

et dans la méthode de construction, vous pouvez vérifier la valeur de l'utilisateur puis passer les widgets.

Usermode user;

@override
void initState() {
super.initState();
_getUser();

}

Void _getUser() async {
user = await UserManagement().getUserProfile();
setState(() {});
}

Désormais, chaque fois que les données utilisateur sont chargées, elles appelleront setState () et votre page de profil se chargera.

Pour cela vous devez créer - Usermode user; variable d'état.


0 commentaires

0
votes

Après avoir fait beaucoup de recherches, j'ai fini par utiliser Flutter StreamBuilder . C'était parfait pour ce pour quoi je voulais l'utiliser. J'appelle la méthode UserManagement (). GetUserProfile () et j'obtiens l'instantané des données à partir de la valeur retournée. Si les données sont en cours de chargement, j'affiche le CircularProgressIndicator () . Si l'instantané est nul, j'affiche un message d'erreur. Voir l'extrait de code ci-dessous.

    @override
   Widget build(BuildContext context) {
   return StreamBuilder(
    stream: UserManagement().getClientProfile(curUserID).snapshots(),
    builder: (context, snapshot) {
      if (snapshot.connectionState == ConnectionState.active) {
      UserModel _user = new UserModel.from(snapshot.data)
        return Scaffold(
            body: Column(
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                 Text(_usermodel.name),
            ],
       });
     }else if (snapshot.connectionState == ConnectionState.waiting) {
        return Container(child: Center(child: CircularProgressIndicator()));
      } else {
        return Container(
          child: Column(
            children: <Widget>[
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: Icon(Icons.warning),
              ),
              Text('There was an error please try again')
            ],
          ),
        );
      }
  }

Dans cet exemple, j'utilise StreamBuilder mais vous pouvez également utiliser FutureBuilder . StreamBuilder écoute les modifications des données et met à jour l'interface utilisateur en conséquence tandis que FutureBuilder obtient les données une fois jusqu'à ce que la page soit à nouveau chargée. J'ai dû apporter des modifications à mon UserModel et j'ai également ajusté la façon dont je stockais mes données, mais tout a fonctionné. J'ai obtenu la plupart de ma solution de ici a >


0 commentaires