I'm trying to create a model class with a few methods to simplify retrieving information from Firebase.
I have a "Unregistered" page where user clicks on the "Login with google" button. If my user is already registered it checks the DB to see if he completed his profile, otherwise it writes basic data to the database with a field profileCompleted: false
and redirects the user to the profile page so he can complete his profile.
I'm trying to use a model here, but i'm getting all sorts of errors (just started learning flutter/dart).
I'll share some code, let me know if its not enough!
Unregistered page.
if (user != null) {
await prefs.setString('id', user.uid);
// Check is already sign up
final QuerySnapshot result = await Firestore.instance
.collection('users')
.where('id', isEqualTo: user.uid)
.getDocuments();
final List<DocumentSnapshot> documents = result.documents;
if (documents.length == 0) {
debugPrint("User not in DB ?");
//debugPrint(userInfo.toString());
// Update data to server if new user
Firestore.instance.collection('users').document(user.uid).setData({
'id': user.uid,
'nickname': user.displayName,
'photoUrl': user.photoUrl,
'email': user.email,
'createdAt': DateTime.now(),
'provider': user.providerId,
'profileCompleted': false,
'bloodType': 'A',
'rhType': 'Negativ',
'donatedBefore': 'Nu',
'lastDonation': '0'
});
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CompleteProfile(
currentUserId: user.uid,
userInfo: documents.single,
)));
} else if (documents.single["profileCompleted"] == false) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CompleteProfile(
currentUserId: user.uid,
userInfo: documents.single,
)));
} else {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HomePage(
currentUserId: user.uid,
userInfo: documents.single,
)));
}
}
Complete profile page
class CompleteProfile extends StatefulWidget {
final String currentUserId;
final userInfo;
static const routeName = '/profile';
final User user;
CompleteProfile(
{Key key,
this.title,
@required this.currentUserId,
@required this.userInfo,
this.user})
: super(key: key);
final String title;
@override
_CompleteProfileState createState() => _CompleteProfileState(user,
currentUserId: this.currentUserId, userInfo: this.userInfo);
}
class _CompleteProfileState extends State<CompleteProfile> {
User user;
_CompleteProfileState(this.user,
{Key key, @required this.currentUserId, @required this.userInfo});
final String currentUserId;
final userInfo;
My issue here is that if i try to set a dropdown like this ->
child: ListTile(
title: DropdownButton<String>(
items: _bloodTypes.map((String value) {
return DropdownMenuItem<String>(
value: value, child: Text(value));
}).toList(),
style: textStyle,
value: retrieveBloodType(user.bloodType),
onChanged: (value) => updateBloodType(value),
And on default value->
String retrieveBloodType(String value) {
return _bloodType;
}
I get an error that i'm getting on null.
My idea was to initialize the User
model with something like User user = new User(userInfo["id"],userInfo["email"]....
in which userInfo
is an object retrieved from firebase. However, that throws another error that only static members can be accessed in initalizers.
My model is quite simple so here's a sneak peek (few lines, not the entire model).
class User {
int _id;
String _nickname;
int get id => _id;
String get nickname => _nickname;
set bloodType(String newBloodType) {
if (newBloodType.length <= 50 && newBloodType != null) {
_bloodType = newBloodType;
}
}
Any idea on how id have to change this to work? The only reason i'm thinking of using models is to simplify screen widgets (so i can add all firebase logic to the model instead of the widgets).