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.