firebase - 无法使用颤振创建帐户,ErrorPlatformException(错误,给定字符串为空或 null,null)
问题描述
我已经坚持了好几天了。我所有相关的文件都附在下面。问题是我无法使用flutter和firebase注册电子邮件和密码。它一直给我这个错误 ErrorPlatformException(error, Given String is empty or null, null)。任何帮助,将不胜感激。
对不起,这太长了,我对编程和颤振/火力比较陌生
1)这部分做映射(Mapping.dart):
`import 'package:flutter/material.dart';
import 'LoginRegisterPage.dart';
import 'Homepage.dart';
import 'Authentication.dart';
class MappingPage extends StatefulWidget{
final AuthImplementation auth;
MappingPage(
{
this.auth,
}
);
State<StatefulWidget> createState(){
return _MappingPageState();
}
}
enum AuthStatus{
notSignedIn,
signedIn,
}
class _MappingPageState extends State<MappingPage>{
AuthStatus authStatus = AuthStatus.notSignedIn;
void initState(){
super.initState();
widget.auth.GetCurrentUser().then((firebaseUserId)
{
setState(() {
authStatus = (firebaseUserId == null) ? AuthStatus.notSignedIn : AuthStatus.signedIn;
//If Id==null user not signed in else user signed in
});
}).catchError((onError){
authStatus = AuthStatus.notSignedIn;
});
}
void _signedIn(){
setState(() {
authStatus = AuthStatus.signedIn;
});
}
void _signedOut(){
setState(() {
authStatus = AuthStatus.notSignedIn;
});
}
@override
Widget build(BuildContext context) {
switch(authStatus){
case AuthStatus.notSignedIn:
return new LoginRegisterPage(
auth: widget.auth,
onSignedIn: _signedIn,
);
case AuthStatus.signedIn:
return new Homepage(
auth: widget.auth,
onSignedOut: _signedOut,
);
}
}
}`
2)此部分用于登录和注册(LoginRegisterPage.dart):
`import 'package:flutter/material.dart';
import 'Authentication.dart';
class LoginRegisterPage extends StatefulWidget{
LoginRegisterPage({
this.auth,
this.onSignedIn, onSignedOut,
});
final AuthImplementation auth;
final VoidCallback onSignedIn;
State<StatefulWidget> createState(){
return _LoginRegisterState();
}
}
enum FormType{
login,
register
}
class _LoginRegisterState extends State <LoginRegisterPage>{
final formKey = new GlobalKey<FormState>();
FormType _formType =FormType.login;
String _email = "";
String _password ="";
String _fname = "";
String _lname ="";
//methods
bool validateSave(){
final form = formKey.currentState;
if(form.validate()){
form.save();
return true;
}
else{
return false;
}
}
void validateSubmit() async{
if(validateSave()){
try{
if(_formType == FormType.login){
String userId = await widget.auth.SignIn(_email, _password);
print("login userId" + userId);
}
else{
String userId = await widget.auth.SignUp(_email, _password);
print("register userId" + userId);
}
widget.onSignedIn();
}
catch(e){
print("Error" + e.toString());
}
}
}
void moveReg(){
formKey.currentState.reset();
setState(() {
_formType = FormType.register;
});
}
void moveLogin(){
formKey.currentState.reset();
setState(() {
_formType = FormType.login;
});
}
//Designs
@override
Widget build(BuildContext context) {
return new Scaffold(
resizeToAvoidBottomPadding: false,
appBar: new AppBar(
title: new Text("URBAN ESTATE"),
centerTitle: true,
),
body: new Container(
margin: EdgeInsets.all(15.0),
child: new Form(
key: formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: createInputs() + createButtons(),
),
),
),
);
}
List<Widget> createInputs(){
if(_formType == FormType.login){
return[
SizedBox(height: 10.0,),
logo(),
SizedBox(height: 20.0,),
new TextFormField(
decoration: new InputDecoration(
labelText: "Email"
),
validator: (value){
return value.isEmpty ? "Please enter a valid email": null;
},
onSaved: (value){
return _email = value;
},
),
SizedBox(height: 10.0,),
new TextFormField(
decoration: new InputDecoration(
labelText: "Password"
),
validator: (value){
return value.isEmpty ? "Please enter a valid password": null;
},
onSaved: (value){
return _password = value;
},
),
SizedBox(height: 20.0,),
];
}
else if(_formType == FormType.register){
return[
SizedBox(height: 20.0,),
new TextFormField(
decoration: new InputDecoration(
labelText: "First Name"
),
validator: (value){
return value.isEmpty ? "This is a required field": null;
},
onSaved: (value){
return _fname = value;
},
),
SizedBox(height: 10.0,),
new TextFormField(
decoration: new InputDecoration(
labelText: "Last Name"
),
validator: (value){
return value.isEmpty ? "This is a required field": null;
},
onSaved: (value){
return _lname = value;
},
),
SizedBox(height: 10.0,),
new TextFormField(
decoration: new InputDecoration(
labelText: "Email"
),
validator: (value){
return value.isEmpty ? "Please enter a valid email": null;
},
onSaved: (value){
return _email = value;
},
),
SizedBox(height: 10.0,),
new TextFormField(
decoration: new InputDecoration(
labelText: "Password"
),
obscureText: true,
validator: (value){
return value.isEmpty ? "Please enter a valid password": null;
},
onSaved: (value){
return _email = value;
},
),
SizedBox(height: 20.0,),
];
}
}
Widget logo(){
return new Hero(
tag: "hero",
child: new CircleAvatar(
backgroundColor: Colors.transparent,
radius: 110.0,
child: Image.asset("assets/Logo1.png"),
),
);
}
List<Widget> createButtons(){
if(_formType == FormType.login){
return[
new RaisedButton(
onPressed: validateSubmit,
child: new Text("Login", style: new TextStyle(fontSize:20.0,) ),
textColor: Colors.black,
color: Colors.amber,
),
new FlatButton(
onPressed: () => moveReg(),
child: new Text("Register", style: new TextStyle(fontSize:18.0, ) ),
textColor: Colors.black,
)
];
}
else if(_formType == FormType.register){
return[
new RaisedButton(
onPressed: validateSubmit,
child: new Text("Create Account", style: new TextStyle(fontSize:20.0,) ),
textColor: Colors.black,
color: Colors.amber,
),
new FlatButton(
onPressed: moveLogin,
child: new Text("Already have an account? Login again", style: new TextStyle(fontSize:18.0, ) ),
textColor: Colors.black,
)
];
}
}
}`
3)本节用于身份验证(Authentication.dart):
`import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
abstract class AuthImplementation {
Future<String> SignIn(String email, String password);
Future<String> SignUp(String email, String password);
Future<String> GetCurrentUser();
Future<void> SignOut();
}
class Auth implements AuthImplementation{
final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
Future<String> SignIn(String email, String password) async
{
FirebaseUser user = (await _firebaseAuth.signInWithEmailAndPassword(email: email, password: password)).user;
return user.uid;
}
Future<String> SignUp(String email, String password) async
{
AuthResult rawUser = await _firebaseAuth.createUserWithEmailAndPassword(email: email, password: password);
FirebaseUser user = (rawUser).user;
return user != null ? user.uid : null;
}
Future<String> GetCurrentUser()async{
FirebaseUser user = await _firebaseAuth.currentUser();
return user != null ? user.uid : null;
}
Future<void> SignOut() async{
_firebaseAuth.signOut();
}
}`
4)这是我在控制台上得到的:
`Restarted application in 1,528ms.
W/IInputConnectionWrapper( 5035): getSelectedText on inactive InputConnection
W/IInputConnectionWrapper( 5035): requestCursorAnchorInfo on inactive InputConnection
W/IInputConnectionWrapper( 5035): getTextBeforeCursor on inactive InputConnection
W/IInputConnectionWrapper( 5035): getTextBeforeCursor on inactive InputConnection
E/MethodChannel#plugins.flutter.io/firebase_auth( 5035): Failed to handle method call
E/MethodChannel#plugins.flutter.io/firebase_auth( 5035): java.lang.IllegalArgumentException: Given String is empty or null
E/MethodChannel#plugins.flutter.io/firebase_auth( 5035): at com.google.android.gms.common.internal.Preconditions.checkNotEmpty(Unknown Source)
E/MethodChannel#plugins.flutter.io/firebase_auth( 5035): at com.google.firebase.auth.FirebaseAuth.createUserWithEmailAndPassword(com.google.firebase:firebase-auth@@19.2.0:256)
E/MethodChannel#plugins.flutter.io/firebase_auth( 5035): at io.flutter.plugins.firebaseauth.FirebaseAuthPlugin.handleCreateUserWithEmailAndPassword(FirebaseAuthPlugin.java:361)
E/MethodChannel#plugins.flutter.io/firebase_auth( 5035): at io.flutter.plugins.firebaseauth.FirebaseAuthPlugin.onMethodCall(FirebaseAuthPlugin.java:143)
E/MethodChannel#plugins.flutter.io/firebase_auth( 5035): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:226)
E/MethodChannel#plugins.flutter.io/firebase_auth( 5035): at io.flutter.embedding.engine.dart.DartMessenger.handleMessageFromDart(DartMessenger.java:85)
E/MethodChannel#plugins.flutter.io/firebase_auth( 5035): at io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage(FlutterJNI.java:631)
E/MethodChannel#plugins.flutter.io/firebase_auth( 5035): at android.os.MessageQueue.nativePollOnce(Native Method)
E/MethodChannel#plugins.flutter.io/firebase_auth( 5035): at android.os.MessageQueue.next(MessageQueue.java:323)
E/MethodChannel#plugins.flutter.io/firebase_auth( 5035): at android.os.Looper.loop(Looper.java:136)
E/MethodChannel#plugins.flutter.io/firebase_auth( 5035): at android.app.ActivityThread.main(ActivityThread.java:6119)
E/MethodChannel#plugins.flutter.io/firebase_auth( 5035): at java.lang.reflect.Method.invoke(Native Method)
E/MethodChannel#plugins.flutter.io/firebase_auth( 5035): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
E/MethodChannel#plugins.flutter.io/firebase_auth( 5035): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
I/flutter ( 5035): ErrorPlatformException(error, Given String is empty or null, null)`
解决方案
如错误所示,您将传递null
一个空字符串或一个空字符串:
_firebaseAuth.createUserWithEmailAndPassword(email: email, password: password);
这反过来意味着您将传递null
一个空字符串或一个空字符串:
Future<String> SignUp(String email, String password) async
在调用堆栈之后,意味着null
/empty 字符串来自:
String userId = await widget.auth.SignUp(_email, _password)
您设置的唯一位置_email
是在这些方法中:
onSaved: (value){
return _email = value;
},
如果我然后扫描所有这些方法,您似乎永远不会_password
以相同的方式进行设置。事实上,我认为这可能是你的问题:
new TextFormField(
decoration: new InputDecoration(
labelText: "Password"
),
obscureText: true,
validator: (value){
return value.isEmpty ? "Please enter a valid password": null;
},
onSaved: (value){
return _email = value; // Should probably assign to _password
},
),
这是一种非常常见的问题,我倾向于将其称为复制/粘贴/忘记修改。它通常很难发现,因为你的大脑倾向于看到你想要的代码,而不是你实际编写的代码。
自行调试并将搜索天数减少到更合理数量的最佳步骤是:
- 在引发错误的调用上放置一个断点,并检查哪些值是
null
或空的。在这种情况下,这将在调用中指向密码_firebaseAuth.createUserWithEmailAndPassword(email: email, password: password);
。 - 追踪何时何
password
地获得价值,以及可能在哪里失去价值。在这种情况下,这会让您了解我上面给出的其他行。 - 在每个上放置一个断点,并检查值。他们是你期望他们成为的样子吗?如果是这样,请进入代码,看看它在哪里停止做你期望它做的事情。如果它没有正确的值,请继续向上调用堆栈直到它有;然后从那里进入代码。
我基本上做了上面相同的事情来找到问题。但是,如果您自己这样做,您将拥有能够使用调试器的优势,并且可以节省一些时间。
推荐阅读
- mysql - 如何在 MySQL 视图中安全地将名称转换为“经过清理的别名”?
- google-bigquery - BigQuery API 可以使用 create_table()(表插入)覆盖现有表/视图吗?
- c - 代码块运行我的代码并提供所需的输出,但随后说 link.exe 已停止工作
- powershell - Get-Command -Module MicrosoftTeams 不包括 Get-TeamChannelUser cmdlet
- javascript - 无法将字符串转换为数字
- python - Gurobi 多目标函数分层退化
- c++ - 带有“”的字符串标记化,在“.”处中断
- javascript - 如何使用 jquery 获取 php 回显
- javascript - 添加到 header.php 的脚本不会在某些页面上加载,但一旦登录到 wp-dashboard 就会显示在所有页面上
- twitter-bootstrap - 如何在我的项目中使用来自 codepen 的代码