在 null 上调用了 Flutter 方法 'resetPassword'

Flutter method 'resetPassword' was called on null

我试图创建一个允许用户重置密码的按钮。但是,当我使用该方法时,它是在 null 上调用的。

我不知道我哪里做错了。我检查了所有内容,它应该可以工作,因为我已经在名为 BaseAuth 的摘要 class 中实现了该方法。

有人可以帮我吗?

这就是我使用 ResetPasswordPage 的方式

@override
Widget build(BuildContext context) {
_isIos = Theme.of(context).platform == TargetPlatform.iOS;
return new Scaffold(
    appBar: new AppBar(
      title: new Text("Organizer"),
      backgroundColor: Colors.blueAccent,
    ),
    body: Stack(
      children: <Widget>[
        _showBody(),
        _showCircularProgress(),
      ],
    ));
     }
Widget _showBody(){
return new Container(
    padding: EdgeInsets.all(10.0),
    child: new Form(
      key: _formKey,
      child: new ListView(
        shrinkWrap: true,
        children: <Widget>[
          _showEmailInput(),
          _showPasswordInput(),
          _showPrimaryButton(),
          _showSecondaryButton(),
          _resetPassword(),
        ],
      ),
    ));
     }
Widget _resetPassword() {
return new Padding(
  padding: EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 0.0),
child : FlatButton(
  child: new Text('Forget password?',
      style:
      new TextStyle(fontSize: 18.0, fontWeight: FontWeight.w300)),
  onPressed: (){
    Navigator.push(
      context,
      MaterialPageRoute(builder: (context) => ResetPasswordPage()),
    );
  }
)
);
}

这是重置密码页面Class

class ResetPasswordPage extends StatefulWidget {
ResetPasswordPage({Key key, this.auth});
final BaseAuth auth;
@override
_ResetPasswordPageState createState() => _ResetPasswordPageState();
}
class _ResetPasswordPageState extends State<ResetPasswordPage> {
String _email = '';
TextEditingController _emailController;
@override
void initState() {
super.initState();
final _emailController = TextEditingController(text: _email);
}

@override
void dispose() {
// Clean up the controller when the widget is disposed.
_emailController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
    appBar: new AppBar(
      title: new Text('Reset Password Page'),
      backgroundColor: Colors.red,
    ),
    body: Container(
      padding: EdgeInsets.all(10.0),
      child: ListView(
        children: <Widget>[
          new Padding(
            padding: const EdgeInsets.fromLTRB(0.0, 100.0, 0.0, 0.0),
            child: new TextField(
              maxLines: 1,
              keyboardType: TextInputType.emailAddress,
              decoration: new InputDecoration(
                  hintText: 'Email',
                  icon: new Icon(
                    Icons.mail,
                    color: Colors.grey,
                  )),
              onChanged: (value) {
                _email = value;
              },
              controller: _emailController,
            ),
          ),
          new Padding(
              padding: const EdgeInsets.fromLTRB(30.0, 20.0, 30.0, 0.0),
              child: RaisedButton(
                child: new Text('Sumbit',
                    style: new TextStyle(
                        fontSize: 18.0, fontWeight: FontWeight.w300)),
                onPressed: () async{
                  try{
                    await widget.auth.resetPassword('guanwenyan301@gmail.com');
                  }catch(e){
                    print(e);
                  }
                },
              ))
        ],
      ),
    ));
    }
     }

这是我的 BaseAuth Class:

abstract class BaseAuth {

Future<String> signIn(String email, String password);
Future<String> signUp(String email, String password);
Future<FirebaseUser> getCurrentUser();
Future<void> signOut();
Future<void> resetPassword(String email);}

class Auth implements BaseAuth {
final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
Future<String> signIn(String email, String password) async {
FirebaseUser user = await _firebaseAuth.signInWithEmailAndPassword(
    email: email, password: password);
if (user.isEmailVerified) {
  return user.uid;
}else{
  Fluttertoast.showToast(msg: 'Please verify your email');
}
}

Future<String> signUp(String email, String password) async {
FirebaseUser user = await _firebaseAuth.createUserWithEmailAndPassword(
    email: email, password: password);
await user.sendEmailVerification();
return user.uid;
}

Future<FirebaseUser> getCurrentUser() async {
FirebaseUser user = await _firebaseAuth.currentUser();
return user;
}

Future<void> signOut() async {
return _firebaseAuth.signOut();
}


Future<void> resetPassword(String email) async {
return _firebaseAuth.sendPasswordResetEmail(email: email);

}}

这是我得到的错误:

flutter: NoSuchMethodError: The method 'resetPassword' was called on 
null.
Receiver: null
Tried calling: resetPassword("guanwenyan301@gmail.com")

问题在这里

ResetPasswordPage({Key key, this.auth});
final BaseAuth auth;

当您从主窗口小部件传递身份验证时。但是在你的代码中它丢失了

Navigator.push(
      context,
      MaterialPageRoute(builder: (context) => ResetPasswordPage()),
    );

所以需要创建**Auth**的实例,然后传递给路由中的ResetPasswordPage()

///像这样初始化auth对象

auth = Auth();

/// 并像这样在 onPressed 中传递它

onPressed: (){
    Navigator.push(
      context,
      MaterialPageRoute(builder: (context) => ResetPasswordPage(auth : auth)), // first auth is the key in ResetPasswordPage and second auth is value 
    );
  }

您在未通过身份验证的情况下创建了 ResetPasswordPage:

Navigator.push(
  context,
  MaterialPageRoute(builder: (context) => ResetPasswordPage()),
);

也就是说你的ResetPasswordPage下的auth是空的。 然后你用它来调用 resetPassword() 方法。当然,你会得到例外。

解决方案:

...
onPressed: () {
  var auth = Auth();
  Navigator.push(
    context,
    MaterialPageRoute(builder: (context) => ResetPasswordPage(auth: auth)),
  );
}
...

希望对您有所帮助!