Search code examples
flutterdartfirebase-authenticationflutter-provider

How to get the return of Futur function call with class Provider.of?


I'm building an app with flutter and I have a question about Provider.of. In my Widget I call this :

Provider.of<Auth>(context, listen: false).signup(emailController.text, passwordController.text);

And I would like to navigate with Navigator according to the return of my signup function. I tried multiple other ways but couldn't make it work.

Naively I tried this:

onPressed: () {
  var result = Provider.of<Auth>(context, listen: false)
      .signup(emailController.text,
          passwordController.text);
  if (result == "failed") {
                              Navigator.of(context).push(MaterialPageRoute(
      builder: (ctx) => SuccessfulScreen()));
  } else {
                              Navigator.of(context).push(MaterialPageRoute(
      builder: (ctx) => UnsuccessfulScreen()));
  }
},

But I got this type for the var result: Future<String>

Here is my tree of my project:

lib/
├── firebase_options.dart
├── images
├── main.dart
├── model
│   └── apis
│       └── auth.dart
└── view
    └── screens
        ├── login_screen.dart
        ├── signup_screen.dart
        ├── successful_screen.dart
        └── welcome_screen.dart

And the auth.dart contains this :

import 'package:flutter/foundation.dart';
import 'package:firebase_auth/firebase_auth.dart';

class Auth with ChangeNotifier {
  Future<String> signup(String email, String password) async {
    try {
      await FirebaseAuth.instance.createUserWithEmailAndPassword(
        email: email,
        password: password,
      );
    } on FirebaseAuthException catch (e) {
      if (e.code == 'weak-password') {
        return e.code;
      } else if (e.code == 'email-already-in-use') {
        return e.code;
      }
    } catch (e) {
      return e.toString();
    }
    return "succes";
  }

  Future<void> login(String email, String password) async {
    try {
      await FirebaseAuth.instance
          .signInWithEmailAndPassword(email: email, password: password);
    } on FirebaseAuthException catch (e) {
      if (e.code == 'user-not-found') {
        print('No user found for that email.');
      } else if (e.code == 'wrong-password') {
        print('Wrong password provided for that user.');
      }
    }
  }
}

I could make this logic directly in my build function (login_screen.dart) but I found that not easy to maintain. So I make it difficult for me but my guess is that I'm missing something, could someone help me on this ?


Solution

  • Add the "async" keyword in the body of function and the "await" keyword before the call of your signup method, like this.

    onPressed: () async {
      var result = await Provider.of<Auth>(context, listen: false)
          .signup(emailController.text,
              passwordController.text);
      if (result == "failed") {
          Navigator.of(context).push(MaterialPageRoute(
              builder: (_) => UnsuccessfulScreen()));
      } else {
          Navigator.of(context).push(MaterialPageRoute(
              builder: (_) => SuccessfulScreen()));
      }
    },