Acerca de

Obteniendo los datos del usuario actual de firebase.

Enfoque 1

var currentUser = FirebaseAuth.instance.currentUser;
if (currentUser != null) {
  var user = FirebaseFirestore.instance
      .collection("tblusers")
      .doc(currentUser.uid)
      .get()
      .then((DocumentSnapshot documentSnapshot) {
    if (documentSnapshot.exists) {
      _controllerFirstName.text = documentSnapshot.data()["first_name"];
    }
  });
}

Tengo las líneas de código anteriores que funcionan bien. A continuación se muestra el código completo.

class AccountForm extends StatelessWidget {
  var firstName = "";
  
  TextEditingController _controllerFirstName = new TextEditingController();
  var _accountFormKey = GlobalKey<FormState>();

  @override
  Widget build(BuildContext context) {
    var currentUser = FirebaseAuth.instance.currentUser;
    if (currentUser != null) {
      var user = FirebaseFirestore.instance
          .collection("tblusers")
          .doc(currentUser.uid)
          .get()
          .then((DocumentSnapshot documentSnapshot) {
        if (documentSnapshot.exists) {
          _controllerFirstName.text = documentSnapshot.data()["first_name"];
        }
      });
    }

    return Form(
        key: _accountFormKey,
        autovalidateMode: AutovalidateMode.onUserInteraction,
        child: Column(children: <Widget>[
          Container(
              margin: EdgeInsets.symmetric(horizontal: 10),
              child: Column(children: [
                TextFormField(
                  controller: _controllerFirstName,
                  validator: (value) {
                    if (value.isEmpty) {
                      return "Error";
                    }
                  },
                ),
                ElevatedButton(
                    onPressed: () {
                      if (_accountFormKey.currentState.validate()) {}
                    },
                    child: Text("Submit"))
              ]))
        ]));
  }
}

Luego intenté mejorar el código agregando las clases como se muestra a continuación. El nuevo código se ve a continuación. pero, esto no completa el nombre

Enfoque 2

class UserModel {
  var first_name;

  UserModel(
      {this.first_name});
}

class UserProvider {
  UserModel userModel;

  UserModel getUserData() {
    var currentUser = FirebaseAuth.instance.currentUser;
    if (currentUser != null) {
      var user = FirebaseFirestore.instance
          .collection("tblusers")
          .doc(currentUser.uid)
          .get()
          .then((DocumentSnapshot documentSnapshot) {
        if (documentSnapshot.exists) {
          userModel = UserModel(
              first_name: documentSnapshot.data()["first_name"]
        }
      });
    }
  }
}

Clase de widget

class AccountForm extends StatelessWidget {
  var firstName = "";

  TextEditingController _controllerFirstName = new TextEditingController();

  var _accountFormKey = GlobalKey<FormState>();

  @override
  Widget build(BuildContext context) {
    var provider = new UserProvider();
    var result = provider.getUserData();
    _controllerFirstName.text = result.first_name;

    return Form(
        key: _accountFormKey,
        autovalidateMode: AutovalidateMode.onUserInteraction,
        child: Column(children: <Widget>[
          Container(
              margin: EdgeInsets.symmetric(horizontal: 10),
              child: Column(children: [
                TextFormField(
                  controller: _controllerFirstName,
                  validator: (value) {
                    if (value.isEmpty) {
                      return MinMaxMessages.RequiredFirstName;
                    } 
                  }                  
                ),                
                ElevatedButton(
                    onPressed: () {
                      if (_accountFormKey.currentState.validate()) {}
                    },
                    child: Text("Submit"))
              ]))
        ]));
  }
}
0
Pankaj 21 ene. 2021 a las 19:58

1 respuesta

La mejor respuesta

Hay pocos problemas con su implementación.

Llamar a getUserData() en su método de compilación. Cada vez que se reconstruye este widget, se llama a este método. En cambio, una mejor solución sería convertir esta clase a StatefulWidget y llamarla una vez en el método initState().

El tipo de retorno de getUserData() es UserModel, pero realmente no veo dónde lo devuelve, por lo que este puede ser el problema principal aquí.

Aquí está el código:

class UserModel {
  var first_name;

  UserModel({this.first_name});
}

class UserProvider {
  UserModel getUserData() async {
    var currentUser = FirebaseAuth.instance.currentUser;

    if (currentUser != null) {
      var snapshot = await FirebaseFirestore.instance
          .collection("tblusers")
          .doc(currentUser.uid)
          .get();

      return UserModel(first_name: snapshot.data()["first_name"]);
    }

    return null;
  }
}

Convertí su widget a stateful y agregué el método initState ().

class AccountForm extends StatefulWidget {
  @override
  _AccountFormState createState() => _AccountFormState();
}

class _AccountFormState extends State<AccountForm> {
  var _accountFormKey = GlobalKey<FormState>();

  UserProvider userProvider = new UserProvider();
  TextEditingController controllerFirstName = new TextEditingController();
  UserModel userModel;

  @override
  void initState() {
    super.initState();
    asyncInit();
  }

  void asyncInit() async {
    userModel = await userProvider.getUserData();

    if (userModel != null) {
      controllerFirstName.text = userModel.first_name;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Form(
      key: _accountFormKey,
      autovalidateMode: AutovalidateMode.onUserInteraction,
      child: Column(
        children: <Widget>[
          Container(
            margin: EdgeInsets.symmetric(horizontal: 10),
            child: Column(
              children: [
                TextFormField(
                  controller: controllerFirstName,
                  validator: (value) {
                    if (value.isEmpty) {
                      return MinMaxMessages.RequiredFirstName;
                    }
                  },
                ),
                ElevatedButton(
                  child: Text("Submit"),
                  onPressed: () {
                    if (_accountFormKey.currentState.validate()) {}
                  },
                ),
              ],
            ),
          )
        ],
      ),
    );
  }
}
1
pasty 21 ene. 2021 a las 18:05