Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.6k views
in Technique[技术] by (71.8m points)

flutter - Approach 2 not populating Firstname

About

Fetching the current user data from firebase.

Approach 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"];
    }
  });
}

I have above lines of code that works fine. Below is the full code.

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"))
              ]))
        ]));
  }
}

Then I tried to improve the code by adding the classes as below. New code looks like below. but, this does not populate first name

Approach 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"]
        }
      });
    }
  }
}

Widget class

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"))
              ]))
        ]));
  }
}
question from:https://stackoverflow.com/questions/65832175/approach-2-not-populating-firstname

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

There are few problems with your implementation.

Calling getUserData() in your build method. Every time this widget is rebuild you are calling this method. Instead a better solution would be to convert this class to StatefulWidget and call it once in initState() method.

The return type of getUserData() is UserModel, but i don't really see where you are returning it, so this may be the main issue here.

Here's code:

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

I've converted your widget to stateful and add initState() method.

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...