firebase - Firebase 身份验证,错误:NoSuchMethodError:在 null 上调用了方法“登录”
问题描述
我是 Flutter 的新手,我尝试使用 firebase Auth 进行登录身份验证,但返回“错误:NoSuchMethodError:方法‘登录’被调用为空。”
登录页面:
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_custom_clippers/flutter_custom_clippers.dart';
import 'package:topride/src/pages/login/login_controller.dart';
import 'package:topride/src/pages/register/register_controller.dart';
import 'package:topride/src/pages/register/register_page.dart';
import 'package:topride/src/widgets/button_app.dart';
class LoginPage extends StatefulWidget {
@override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
LoginController _con = new LoginController();
@override
void setState(VoidCallback fn) {
// TODO: implement setState
super.setState(fn);
SchedulerBinding.instance.addPostFrameCallback((timeStamp) {
_con.init(context);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: SingleChildScrollView(
child: Column(
children: [
_bannerApp(),
_textDescription(),
_textLogin(),
SizedBox(height: MediaQuery.of(context).size.height*0.17,),
_textFieldEmail(),
_textFieldPassword(),
_buttonLogin(),
_textDontHaveAccount(),
],
),
),
);
}
Widget _bannerApp(){
return ClipPath(
clipper: WaveClipperTwo(),
child: Container(
color: Colors.black54,
height: MediaQuery.of(context).size.height*0.22,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Image.asset(
'assets/img/logo_app.png',
width: 150,
height: 100,
),
Text(
'Facile et Rapide',
style: TextStyle(
fontFamily: 'Racing',
fontSize: 22,
fontWeight: FontWeight.w700,
color: Colors.white
),
),
],
),
),
);
}
Widget _textDescription(){
return Container(
alignment: Alignment.centerLeft,
margin: EdgeInsets.symmetric(horizontal: 30,vertical: 10),
child: Text('Continuez avec votre',
style: TextStyle(
color: Colors.black54,
fontSize: 20,
fontFamily: 'Nimbus'
),
),
);
}
Widget _textLogin(){
return Container(
alignment: Alignment.centerLeft,
margin: EdgeInsets.symmetric(horizontal: 30),
child: Text('Login',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 28,
),
),
);
}
Widget _textFieldEmail(){
return Container(
margin: EdgeInsets.symmetric(horizontal: 30,vertical: 10),
child: TextField(
controller: _con.emailController,
decoration: InputDecoration(
hintText: 'example@gmail.com',
labelText: 'Address E-mail',
suffixIcon: Icon(
Icons.email_outlined,
color: Colors.black54,
),
),
),
);
}
Widget _textFieldPassword(){
return Container(
margin: EdgeInsets.symmetric(horizontal: 30,vertical: 15),
child: TextField(
obscureText: true,
controller: _con.passwordController,
decoration: InputDecoration(
labelText: 'Mot de Passe',
suffixIcon: Icon(
Icons.lock_clock_outlined,
color: Colors.black54,
),
),
),
);
}
Widget _buttonLogin (){
return Container(
margin: EdgeInsets.symmetric(horizontal: 30,vertical: 25),
child: ButtonApp(onPressed:_con.login,text:'Connexion',));
}
Widget _textDontHaveAccount(){
return
TextButton(onPressed:() => navigateToRegister(context),
child: Container(
margin: EdgeInsets.only(bottom: 50),
child: Text(
'Ne pas avoir de compte ? ', style: TextStyle(
color: Colors.black54,
fontSize: 15,
),
),
),
);
}
navigateToRegister(BuildContext context) {
Navigator.of(context)
.push(MaterialPageRoute<Null>(builder: (BuildContext context) {
return RegisterPage();
}));
}
}
登录控制器:
import 'package:flutter/material.dart';
import 'package:topride/src/providers/auth_provider.dart';
class LoginController{
BuildContext context;
TextEditingController emailController = new TextEditingController();
TextEditingController passwordController = new TextEditingController();
AuthProvider _authProvider;
Future init(BuildContext context){
this.context=context;
_authProvider=new AuthProvider();
}
void login()async{
String email = emailController.text.trim();
String password =passwordController.text.trim();
print('email: $email');
print('password: $password');
try{
bool isLogin= await _authProvider.login(email, password);
if(isLogin){
print('the user is logged in ');
}
else{
print('the user is not login');
}
}catch(error){
print('Error: $error');
}
}
}
身份验证提供者:
import 'package:firebase_auth/firebase_auth.dart';
class AuthProvider {
FirebaseAuth _firebaseAuth;
AuthProvider(){
_firebaseAuth = FirebaseAuth.instance;
}
Future<bool> login(String email ,String password)async{
String errorMessage;
try{
await _firebaseAuth.signInWithEmailAndPassword(email: email, password: password);
}catch(error){
print(error);
//invalid email
//incorrect password
//no internet connection
errorMessage=error.Code;
}
if(errorMessage!=null){
return Future.error(errorMessage);
}
return true;
}
}
跑:
I/flutter (10810): email: ahmed.alqasim@gmail.com
I/flutter (10810): password: 37503230
I/flutter (10810): Error: NoSuchMethodError: The method 'login' was called on null.
I/flutter (10810): Receiver: null
I/flutter (10810): Tried calling: login("ahmed.alqasim@gmail.com", "37503230")
我还在firebase上添加帐户希望相同的电子邮件和密码进行测试,请帮助这让我发疯
解决方案
在您的小部件中,是否有您覆盖方法LoginPage
的特定原因?setState
我假设您想initState
改用。以下是为您推荐的片段:
LoginController _con = new LoginController();
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) async {
await _con.init(context);
setState((){}); //this line is necessary for the widget to know the controller has been updated
});
}
然后,如果您想确保仅在初始化的控制器上调用登录方法,您可以在控制器中添加一个字段,例如bool _isInitialized = false
并将其在您的init
方法中更新为true
.
此外,如果您不需要调用任何async
方法,而不是在您的 中使用 asyncinit
函数LoginController
,您可以只使用默认构造函数:
LoginController(this.context) {
_authProvider = new AuthProvider();
}
顺便说一句,new
Flutter 中的关键字是可选的,因此您可以在使用它的任何地方将其删除。
推荐阅读
- python - 正则表达式 - 从电子邮件链中同一个人发送或回复的电子邮件中提取所有内容
- django - 使用 Models.py 中使用的选项在 Django 中路由页面
- python - 为什么这个多层感知器的损失不低于1
- matlab - 如何解释相关结果?
- java - 从读取特殊字符的 AIX java 代码中获得不同的结果
- excel - 如果数字在范围内,Excel 返回真
- artifactory - 将多个发行版的 debian 包部署到 Jfrog Artifactory 中?
- python - 如何在 Jupyter 中合并日期时间列
- javascript - 在 JS 中制作 Atom 包:转到行
- mysql - 锁定表会导致 django 的保存点问题