简体   繁体   中英

Manually entered data not being saved in Firebase document

I have a screen with several text fields and some are populated when it is created. This is done in the initState() function. When I enter data into the empty text fields and then save the data to a firebase document only the data that is manually entered after the screen has been created is saved to the document. Below is the code for the screen. Please help with this.

final _firebaseAuthUser = FirebaseAuth.instance.currentUser;
final agentsRef = FirebaseFirestore.instance.collection(('agents'));
final agencyRef = FirebaseFirestore.instance.collection(('agency'));

class AgentProfileScreen extends StatefulWidget {
  static const String id = 'agent_profile_screen';
  final Agents agents;

  AgentProfileScreen([this.agents]);

  @override
  _AgentProfileScreenState createState() => _AgentProfileScreenState();
}

class _AgentProfileScreenState extends State<AgentProfileScreen> {
  //final _auth = FirebaseAuth.instance;
  final _db = FirebaseFirestore.instance;

  final emailController = TextEditingController();
  final passwordController = TextEditingController();
  final fNameController = TextEditingController();
  final lNameController = TextEditingController();
  final address1Controller = TextEditingController();
  final address2Controller = TextEditingController();
  final cityController = TextEditingController();
  final stateController = TextEditingController();
  final zipController = TextEditingController();
  final cellPhoneController = TextEditingController();
  final officePhoneController = TextEditingController();
  final agencyController = TextEditingController();

  @override
  void dispose() {
    emailController.dispose();
    passwordController.dispose();
    fNameController.dispose();
    lNameController.dispose();
    address1Controller.dispose();
    address2Controller.dispose();
    cityController.dispose();
    stateController.dispose();
    zipController.dispose();
    cellPhoneController.dispose();
    officePhoneController.dispose();
    agencyController.dispose();
    super.dispose();
  }

  bool showSpinner = false;
  String email;
  String password;
  String fName;
  String lName;
  String address1;
  String address2;
  String city;
  String state;
  String zip;
  String cellPhone;
  String officePhone;
  String agency;

  String _currentAgentState;
  String _currentAgency;

  getCurrentAgentProfile() async {
    final DocumentSnapshot currentAgentProfile =
        await agentsRef.doc(globals.currentUid).get();

    //String currentAgencyId = currentAgentProfile.data()["agencyId"];
    final DocumentSnapshot currentAgencyProfile =
        await agencyRef.doc(globals.agencyId).get();

    if (globals.newAgent == true) {
      emailController.text = "";
      fNameController.text = "";
      lNameController.text = "";
      address1Controller.text = currentAgencyProfile.data()['address1'];
      address2Controller.text = currentAgencyProfile.data()['address2'];
      cityController.text = currentAgencyProfile.data()['city'];
      stateController.text = currentAgencyProfile.data()['state'];
      globals.currentAgencyState = currentAgencyProfile.data()['state'];
      zipController.text = currentAgencyProfile.data()['zipCode'].toString();
      cellPhoneController.text = currentAgencyProfile.data()['cellPhone'];
      officePhoneController.text = currentAgencyProfile.data()['officePhone'];
      agencyController.text = currentAgencyProfile.data()['name'];
    } else {
      // existing record
      // Updates Controllers
      emailController.text = currentAgentProfile.data()["email"];
      fNameController.text = currentAgentProfile.data()['fName'];
      lNameController.text = currentAgentProfile.data()['lName'];
      address1Controller.text = currentAgentProfile.data()['address1'];
      address2Controller.text = currentAgentProfile.data()['address2'];
      cityController.text = currentAgentProfile.data()['city'];
      stateController.text = currentAgentProfile.data()['state'];
      zipController.text = currentAgentProfile.data()['zipCode'].toString();
      cellPhoneController.text = currentAgentProfile.data()['cellPhone'];
      officePhoneController.text = currentAgentProfile.data()['officePhone'];
      agencyController.text = currentAgentProfile.data()['agency'];

      // Updates State
      new Future.delayed(Duration.zero, () {
        final agentProvider =
            Provider.of<AgentProvider>(context, listen: false);
        agentProvider.loadValues(widget.agents);
      });
    }
  }

  List<DropdownMenuItem<String>> _dropDownState;

  List<DropdownMenuItem<String>> getDropDownState() {
    List<DropdownMenuItem<String>> items = [];
    for (String state in globals.states) {
      items.add(new DropdownMenuItem(
          value: state,
          child: new Text(
            state,
          )));
    }
    return items;
  }

  void changedDropDownState(String selected_state) {
    setState(() {
      _currentAgentState = selected_state;
    });
    globals.selectedAgentState = selected_state;
  }

  void changedDropDownAgency(String selected_agency) {
    setState(() {
      _currentAgency = selected_agency;
    });
    globals.selectedAgency = selected_agency;
  }

  @override
  void initState() {
    getCurrentAgentProfile();
    _currentAgentState = globals.currentAgentState;
    _currentAgency = globals.agencyId;
    _currentAgentState = globals.currentAgencyState;
    super.initState();

    _dropDownState = getDropDownState();
  }

  @override
  Widget build(BuildContext context) {
    // Get the stream of agents created in main.dart
    final agentProvider = Provider.of<AgentProvider>(context);
    final _firestoreService = FirestoreService();
    String _chosenState = 'Select State';

    return Scaffold(
      appBar: AppBar(
        title: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Image.asset('assets/images/Appbar_logo.png',
                fit: BoxFit.cover, height: 56),
          ],
        ),
      ),
      backgroundColor: Colors.white,
      body: SafeArea(
        child: SingleChildScrollView(
          child: Padding(
            padding: const EdgeInsets.all(20.0),
            child: Column(
              //mainAxisAlignment: MainAxisAlignment.center,
              //crossAxisAlignment: CrossAxisAlignment.stretch,
              children: <Widget>[
                Text(
                  'Agent Profile',
                  style: TextStyle(
                    fontSize: 30,
                  ),
                ),
                SizedBox(
                  height: 8.0,
                ),
                // Email entry text field
                TextField(
                  controller: fNameController,
                  keyboardType: TextInputType.text,
                  textAlign: TextAlign.center,
                  onChanged: (value) {
                    agentProvider.changefName(value);
                  },
                  decoration: kTextFieldDecoration.copyWith(
                      hintText: 'First Name', labelText: 'First Name'),
                ),
                SizedBox(
                  height: 8.0,
                ),
                TextField(
                  controller: lNameController,
                  keyboardType: TextInputType.text,
                  textAlign: TextAlign.center,
                  onChanged: (value) {
                    agentProvider.changelName(value);
                  },
                  decoration: kTextFieldDecoration.copyWith(
                      hintText: 'Last Name', labelText: 'Last Name'),
                ),
                SizedBox(
                  height: 8.0,
                ),
                Container(
                  child: StreamBuilder(
                      stream: _db.collection('agency').snapshots(),
                      builder: (BuildContext context, AsyncSnapshot snapshot) {
                        if (snapshot.data == null) {
                          return Center(
                            child: CircularProgressIndicator(),
                          );
                        } else {
                          return new DropdownButton<String>(
                            hint: new Text("Select Agency"),
                            value: _currentAgency,
                            onChanged: changedDropDownAgency,
                            items: snapshot.data.docs
                                .map<DropdownMenuItem<String>>((document) {
                              return new DropdownMenuItem<String>(
                                value: document.id,
                                child: new Text(document.data()['name']),
                              );
                            }).toList(),
                          );
                        }
                        ;
                      }),
                ),
                SizedBox(
                  height: 8.0,
                ),
                TextField(
                  controller: address1Controller,
                  keyboardType: TextInputType.text,
                  textAlign: TextAlign.center,
                  onChanged: (value) {
                    agentProvider.changeaddress1(value);
                  },
                  decoration: kTextFieldDecoration.copyWith(
                      hintText: 'Address 1', labelText: 'Address 1'),
                ),
                SizedBox(
                  height: 8.0,
                ),
                TextField(
                  controller: address2Controller,
                  textAlign: TextAlign.center,
                  onChanged: (value) {
                    agentProvider.changeaddress2(value);
                  },
                  decoration: kTextFieldDecoration.copyWith(
                      hintText: 'Address 2', labelText: 'Address 2'),
                ),
                SizedBox(
                  height: 8.0,
                ),
                TextField(
                  controller: cityController,
                  keyboardType: TextInputType.emailAddress,
                  textAlign: TextAlign.center,
                  onChanged: (value) {
                    agentProvider.changecity(value);
                  },
                  decoration: kTextFieldDecoration.copyWith(
                      hintText: 'City', labelText: 'City'),
                ),
                SizedBox(
                  height: 8.0,
                ),
                DropdownButton(
                  value: _currentAgentState,
                  items: _dropDownState,
                  hint: Text('Choose State'),
                  onChanged: changedDropDownState,
                ),
                SizedBox(
                  height: 8.0,
                ),
                TextField(
                  controller: zipController,
                  keyboardType: TextInputType.phone,
                  textAlign: TextAlign.center,
                  onChanged: (value) {
                    agentProvider.changezipCode(value);
                  },
                  decoration: kTextFieldDecoration.copyWith(
                      hintText: 'Zip Code', labelText: 'Zip Code'),
                ),
                SizedBox(
                  height: 8.0,
                ),
                TextField(
                  controller: cellPhoneController,
                  textAlign: TextAlign.center,
                  onChanged: (value) {
                    agentProvider.changecellPhone(value);
                  },
                  decoration: kTextFieldDecoration.copyWith(
                      hintText: 'Cell Phone', labelText: 'Cell Phone'),
                ),
                SizedBox(
                  height: 8.0,
                ),
                TextField(
                  controller: officePhoneController,
                  keyboardType: TextInputType.emailAddress,
                  textAlign: TextAlign.center,
                  onChanged: (value) {
                    agentProvider.changeofficePhone(value);
                  },
                  decoration: kTextFieldDecoration.copyWith(
                      hintText: 'Office Phone', labelText: 'Office Phone'),
                ),
                SizedBox(
                  height: 8.0,
                ),
                RoundedButton(
                  title: 'Save',
                  colour: Colors.blueAccent,
                  onPressed: () async {
                    setState(() {
                      showSpinner = true;
                    });
                    try {
                      agentProvider.saveAgent();
                      globals.newAgent = false;
                      globals.currentAgentState = _currentAgentState;
                      await _firestoreService.saveDeviceToken();
                      Navigator.pushNamed(context, Home_Screen.id);

                      setState(() {
                        showSpinner = false;
                      });
                    } catch (e) {
                      // todo: add better error handling
                      print(e);
                    }
                  },
                ),
                SizedBox(
                  height: 8.0,
                ),

                (widget != null)
                    ? RoundedButton(
                        title: 'Delete',
                        colour: Colors.red,
                        onPressed: () async {
                          setState(() {
                            showSpinner = true;
                          });
                          try {
                            agentProvider.deleteAgent(globals.currentUid);
                            Navigator.pushNamed(
                                context, AgentDashboardScreen.id);

                            setState(() {
                              showSpinner = false;
                            });
                          } catch (e) {
                            // todo: add better error handling
                            print(e);
                          }
                        },
                      )
                    : Container()
              ],
            ),
          ),
        ),
      ),
    );
  }
}

Below is the provider code.

class AgentProvider with ChangeNotifier {
  final firestoreService = FirestoreService();
  final agencyRef = FirebaseFirestore.instance.collection(('agency'));

  String _fName;
  String _lName;
  String _address1;
  String _address2;
  String _city;
  String _state;
  int _zipCode;
  String _cellPhone;
  String _officePhone;
  String _agencyId;
  String _agency;

  //Getters
  String get fName => _fName;
  String get lName => _lName;
  String get address1 => _address1;
  String get address2 => _address2;
  String get city => _city;
  String get state => globals.selectedAgentState;
  int get zipCode => _zipCode;
  String get cellPhone => _cellPhone;
  String get officePhone => _officePhone;
  String get agencyId => globals.agencyId;
  String get agency => _agency;

  //Setters

  changefName(String value) {
    _fName = value;
    notifyListeners();
  }

  changelName(String value) {
    _lName = value;
    notifyListeners();
  }

  changeaddress1(String value) {
    _address1 = value;
    notifyListeners();
  }

  changeaddress2(String value) {
    _address2 = value;
    notifyListeners();
  }

  changecity(String value) {
    _city = value;
    notifyListeners();
  }

  changestate(String value) {
    _state = value;
    notifyListeners();
  }

  // Convert String to int
  changezipCode(String value) {
    _zipCode = int.parse(value);
    notifyListeners();
  }

  // Convert String to int
  changecellPhone(String value) {
    _cellPhone = value;
    notifyListeners();
  }

  // Convert String to int
  changeofficePhone(String value) {
    _officePhone = value;
    notifyListeners();
  }

  changeAgency(String value) {
    _agency = value;
    notifyListeners();
  }

  loadValues(Agents agents) {
    _fName = agents.fName;
    _lName = agents.lName;
    _address1 = agents.address1;
    _address2 = agents.address2;
    _city = agents.city;
    _state = globals.selectedAgentState;
    _zipCode = agents.zipcode;
    _cellPhone = agents.cellPhone;
    _officePhone = agents.officePhone;
    _agencyId = globals.agencyId;
    _agency = agents.agency;
  }

  saveAgent() async {
    final newAgent = new Map();
    if (globals.newAgent == true) {
      final DocumentSnapshot currentAgencyProfile =
          await agencyRef.doc(globals.agencyId).get();
      var newAgent = Agents(
          agentId: globals.currentUid,
          fName: _fName,
          lName: _lName,
          address1: currentAgencyProfile.data()['address1'],
          address2: currentAgencyProfile.data()['address2'],
          city: currentAgencyProfile.data()['city'],
          state: globals.selectedAgentState,
          zipcode: currentAgencyProfile.data()['zipCode'],
          cellPhone: currentAgencyProfile.data()['cellPhone'],
          officePhone: currentAgencyProfile.data()['officePhone'],
          agencyId: globals.agencyId,
          agency: agency);
      firestoreService.saveAgent(newAgent);
    } else {
      var newAgent = Agents(
          agentId: globals.currentUid,
          fName: _fName,
          lName: _lName,
          address1: _address1,
          address2: _address2,
          city: _city,
          state: globals.selectedAgentState,
          zipcode: _zipCode,
          cellPhone: _cellPhone,
          officePhone: _officePhone,
          agencyId: globals.agencyId,
          agency: agency);
      firestoreService.saveAgent(newAgent);
    }
    //firestoreService.saveAgent(newAgent);

    _fName = "";
    _lName = "";
    _address1 = "";
    _address2 = "";
    _city = "";
    _state = "";
    _zipCode = null;
    _cellPhone = "";
    _officePhone = "";
    _agencyId = "";
    _agency = "";
  }

Here is the saveAgent function. I really don't think this is the problem but here it is anyway.

Future<void> saveAgent(Agents agents) {
    return _db.collection('agents').doc(globals.currentUid).set(agents.toMap());
  }

initState is designed to be a synchronous function, and since your async function will take some time to execute, it will not work out as you expect. To call async function make use of FutureBuilder widget inside your build function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM