0

During the email app signup process using firebaseAuth.createUserWithEmailAndPassword, when I try to do an upload or save to prefs in the .then part it throws this error: NoSuchMethodError: The getter 'data' was called on null.

So I can work around this by Navigating to a new screen and postponing processing of the user's TextFormField input till there, but it's messy and bugs me.

Doing anything big in the .then seems problematic but I don't really know what's causing the problem, or what in fact the best way is to solve this kind of issue for future clarity. Education appreciated!

 void registerToFb() { firebaseAuth .createUserWithEmailAndPassword( email: emailController.text, password: passwordController.text) .then((result) async { Person user = new Person(); user.email = emailController.text; user.firstName = firstNameController.text; user.surname = surnameController.text; user.postcode = postcodeController.text; user.password = passwordController.text; user.city = cityController.text ?? "Edinburgh"; user.firebaseId = result.user.uid; Map<String, dynamic> firebaseUpload = user.toMap(); print("Attempting to reduce upload"); firebaseUpload.removeWhere((key, value) => value == null); user.country = "GB"; String path = "${user.country}/${user.city}/People"; print("Attempting record upload"); DocumentReference autoId = await myFirestore.collection(path).add(firebaseUpload); user.personId = autoId.id; user.saveToPrefs(prefs); Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => MyHomePage())); }).catchError((err) { print("Login thrown an error...\n${err.toString()}"); showDialog( context: context, builder: (BuildContext context) { return AlertDialog( title: Text("Error 10"), content: Text("${err.toString()}"), actions: [ ElevatedButton( child: Text("Ok"), onPressed: () { Navigator.of(context).pop(); }, ) ], ); }); }); 

1 Answer 1

1

A suggestion from me is to completely remove the .then() callback, since you have it stated as async. A better approach would be to make the whole function async, so you can do all your async code directly inside that.

  1. Make the function async
void registerToFb() async { ... 
  1. Change the .then() callback to a simple await and store the result in your result variable.
var result = await firebaseAuth.createUserWithEmailAndPassword(email: emailController.text, password: passwordController.text); 
  1. I would highly suggest surrounding this statement with a try/catch block, to avoid unhandled errors:
try { var result = await firebaseAuth.createUserWithEmailAndPassword( email: emailController.text, password: passowrdController.text ); } on FirebaseAuthException catch (e) { if (e.code == 'weak-password') { print('password too weak.'); } else if (e.code == 'email-already-in-use') { print('email already exists'); } } catch (e) { print(e); } 
  1. You might get this error because you marked the .then() call as async, since it then executes asynchronously and the data might not be "there" yet, but I am not sure about this one.
Sign up to request clarification or add additional context in comments.

1 Comment

Cheers for the thoughtful answer. It solved it, turns out that when turning my user Person object into a map for Firebase upload there was a bug. This bug wasn't flagged in logs till I did as you said, Async-ed the whole function & eliminated the .then. Next issue now, hurrah @Irsvmb!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.