首页 > 解决方案 > 无法使用颤振创建帐户,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)`

标签: firebaseflutterfirebase-authentication

解决方案


如错误所示,您将传递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
    },
  ),

这是一种非常常见的问题,我倾向于将其称为复制/粘贴/忘记修改。它通常很难发现,因为你的大脑倾向于看到你想要的代码,而不是你实际编写的代码。

自行调试并将搜索天数减少到更合理数量的最佳步骤是:

  1. 在引发错误的调用上放置一个断点,并检查哪些值是null或空的。在这种情况下,这将在调用中指向密码_firebaseAuth.createUserWithEmailAndPassword(email: email, password: password);
  2. 追踪何时何password地获得价值,以及可能在哪里失去价值。在这种情况下,这会让您了解我上面给出的其他行。
  3. 在每个上放置一个断点,并检查值。他们是你期望他们成为的样子吗?如果是这样,请进入代码,看看它在哪里停止做你期望它做的事情。如果它没有正确的值,请继续向上调用堆栈直到它有;然后从那里进入代码。

我基本上做了上面相同的事情来找到问题。但是,如果您自己这样做,您将拥有能够使用调试器的优势,并且可以节省一些时间。


推荐阅读