Flutter Firebase身份验证:Google身份验证似乎无法与Firebase一起使用来验证用户的电话号码

时间:2020-02-08 19:20:37

标签: flutter firebase-authentication

所以这是用于与验证器创建业务的代码,但是我遇到的问题是firebase验证器无法验证电话号码,因为现在它会产生一些我不熟悉的错误。

//import 'package:font_awesome/css/all.css';
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:kyereme/models/business.dart';
import 'package:kyereme/services/business_service.dart';
import 'package:flushbar/flushbar.dart';
import 'package:modal_progress_hud/modal_progress_hud.dart';
import 'package:geolocator/geolocator.dart';

 bool _submitting = false;
 bool isLoading = false;
 final FirebaseAuth _auth = FirebaseAuth.instance;
 class ProfilePage extends StatefulWidget {
   @override
   _ProfilePageState createState() => _ProfilePageState();
 }
 SharedPreferences prefs;
 String id = '';
 //create image file
 File _image;
 //get image  method
 //upload image updated
 class _ProfilePageState extends State<ProfilePage> {
   @override
   Widget build(BuildContext context) {

     // context._formKey = _formKey;
     return Scaffold(
       appBar: AppBar(
         title: Text('Add Account', style: TextStyle(color: Colors.white)),
         centerTitle: true,
         backgroundColor: Colors.lightBlueAccent,
         iconTheme: IconThemeData(
           color: Colors.white,
         ),
       ),
       body: ModalProgressHUD(
           child: Builder(builder: (BuildContext context) {
             return _PhoneSignInSection(Scaffold.of(context));
           }),
           inAsyncCall: _submitting),
     );
   }
 }
 class _PhoneSignInSection extends StatefulWidget {
   _PhoneSignInSection(this._scaffold);
   final ScaffoldState _scaffold;
   @override
   State<StatefulWidget> createState() => _PhoneSignInSectionState();
 }
 class _PhoneSignInSectionState extends State<_PhoneSignInSection> {
   final TextEditingController _phoneNumberController = TextEditingController();
   final TextEditingController _smsController = TextEditingController();
   final TextEditingController _businessNameController = TextEditingController();
   final TextEditingController _productsController = TextEditingController();
   static Position _currentLocation = Position();
   static final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
   String _message = '';
   String _verificationId;
   String photoURL;
   String photoID;
   String _businessTypeValue = 'Food';
   List<String> _locations = [
     'Food',
     'Bar',
     'Entertainment',
     'Gas',
     'Bathroom',
     'Medical',
     'Hospitality',
     'Transportation'
   ];
   @override
   Widget build(BuildContext context) {
  var profilePic = 'images/nav/user-pic-icon.png';

  Future getImage() async  {
       var image = await ImagePicker.pickImage(source: ImageSource.gallery);
       setState(() {
         _image =image;
         print('Image Path $_image');
       });
     }
     void readLocal() async {
       prefs = await SharedPreferences.getInstance();
       id = prefs.getString('id') ?? '';
     }
      uploadPicture(BuildContext context) async{

        /*
         upload the picture 
         new 
        */
       final StorageReference profileImageRef = FirebaseStorage.instance.ref().child("profileImages");
       var timekey = new DateTime.now();
       final StorageUploadTask uploadTask = profileImageRef.child(timekey.toString()+ "jpg").putFile(_image); 
       var firebaseImageStorageURL = await(await uploadTask.onComplete).ref.getDownloadURL();
       photoURL = firebaseImageStorageURL.toString();
     //  print("This is the image url" + photoURL);

     }
     final Size screenSize = MediaQuery.of(context).size;
     return Stack(
       fit: StackFit.expand,
       children: <Widget>[
         Container(
           decoration: BoxDecoration(
             gradient: LinearGradient(
               colors: [
                 Color(0x0cccee).withOpacity(1.0),
                 Color(0x00d8d4).withOpacity(0.8)
               ],
               stops: [0.20, 3.0],
               begin: FractionalOffset.bottomCenter,
             ),
           ),
         ),
         Positioned.fill(
           child: Image.asset(
             'images/splash/background-icon.png',
             fit: BoxFit.fitWidth,
             alignment: Alignment.bottomLeft,
           ),
         ),
         Center(
           child: Container(
             alignment: AlignmentDirectional(0.0, 0.0),
             margin: EdgeInsets.only(
               top: 30.0,
               bottom: 30.0,
             ),
             child: Container(
               constraints: BoxConstraints(
                 maxHeight: screenSize.height - 20,
                 maxWidth: screenSize.width - 60,
               ),
               child: Form(
                 key: _formKey,
                 child: ListView(
                   children: <Widget>[
                     SizedBox(height: 20.0),
                     Row(
                       mainAxisAlignment: MainAxisAlignment.center,
                       children: <Widget>[
                         Align(
                           alignment: Alignment.center,
                           child: CircleAvatar(
                             radius: 60,
                             backgroundColor: Color(0xffffff).withOpacity(1.0),
                             child: CircleAvatar(
                               radius: 55,
                               backgroundColor: Color(0xd8d8d8).withOpacity(1.0),
                               child: ClipOval(
                                 child: SizedBox(
                                   width: 180.0,
                                   height: 180.0,
                                   child:(_image!= null)?Image.file(_image,fit: BoxFit.fill)
                                   :IconButton(
                                     icon: Image.asset(
                                       // this where the profile pic is located at
                                         profilePic),
                                     onPressed: (){
                                         getImage();  
                                     },
                                   ),
                                 ),
                               ),
                             ),
                           ),
                         ),
                         Padding(
                           padding: EdgeInsets.only(top: 60.0),
                           child: IconButton(
                             icon: Icon(
                               Icons.camera_alt,
                               size: 30.0,
                               color: Colors.white,
                             ),
                             onPressed: () {
                              getImage();
                             },
                           ),
                         )
                       ],
                     ),
                     TextFormField(
                       controller: _businessNameController,
                       keyboardType: TextInputType.text,
                       decoration: InputDecoration(labelText: 'Business Name'),
                       validator: (String value) {
                         if (value.isEmpty) {
                           return 'Please enter your business name';
                         }
                       },
                     ),
                     TextFormField(
                       controller: _phoneNumberController,
                       keyboardType: TextInputType.phone,
                       decoration: InputDecoration(labelText: 'Phone Number'),
                       validator: (String value) {
                         if (value.isEmpty) {
                           return 'Phone number (+x xxx-xxx-xxxx)';
                         }
                       },
                     ),
                     Row(
                       mainAxisAlignment: MainAxisAlignment.spaceBetween,
                       children: <Widget>[
                         new Container(
                           padding: EdgeInsets.only(top: 10),
                           child: new Text(
                             "Type of business: ",
                             style: TextStyle(
                                 fontSize: 16, color: Colors.grey[800]),
                           ),
                         ),
                         new Container(
                           padding: EdgeInsets.only(top: 10),
                           child: DropdownButton<String>(
                             value: _businessTypeValue,
                             onChanged: (String newValue) {
                               setState(() {
                                 _businessTypeValue = newValue;
                               });
                             },
                             items: <String>[
                               'Food',
                               'Bar',
                               'Entertainment',
                               'Bathroom',
                               'Medical',
                               'Hospitality',
                               'Transportation'
                             ].map<DropdownMenuItem<String>>((String value) {
                               return DropdownMenuItem<String>(
                                 value: value,
                                 child: Text(
                                   value,
                                   style: TextStyle(color: Colors.grey[800]),
                                 ),
                               );
                             }).toList(),
                           ),
                         ),
                       ],
                     ),
                     Container(
                       width: screenSize.width,
                       height: 50.0,
                       child: RaisedButton(
                         child: Row(
                           children: <Widget>[
                             Icon(Icons.navigation),
                             Text(
                               "Current Location",
                               style: TextStyle(color: Colors.white),
                             )
                           ],
                         ),
                         shape: RoundedRectangleBorder(
                             borderRadius: BorderRadius.circular(10.0)),
                         onPressed: () async {
                           _currentLocation = await Geolocator()
                               .getCurrentPosition(
                                   desiredAccuracy:
                                       LocationAccuracy.bestForNavigation);
                         },
                         color: Colors.transparent,
                       ),
                       margin: EdgeInsets.only(
                         top: 30.0,
                         bottom: 30.0,
                       ),
                       decoration: BoxDecoration(
                         color: Colors.transparent,
                         border: Border.all(color: Colors.white, width: 1.0),
                         borderRadius: BorderRadius.circular(10.0),
                       ),
                     ),
                     TextFormField(
                       controller: _productsController,
                       maxLines: 5,
                       keyboardType: TextInputType.multiline,
                       decoration: InputDecoration(
                           labelText:
                               'Product(s) Instructions on how to input here',
                           border: OutlineInputBorder()),
                     ),
                     Container(
                       alignment: Alignment.center,
                       padding: const EdgeInsets.symmetric(horizontal: 16),
                       child: Text(
                         _message,
                         style: TextStyle(color: Colors.red),
                       ),
                     ),
                     Container(
                       width: screenSize.width,
                       height: 50,
                       child: RaisedButton(
                         child: Text(
                           "Submit",
                           style: TextStyle(color: Colors.white),
                         ),
                         shape: RoundedRectangleBorder(
                             borderRadius: BorderRadius.circular(10.0)),
                         onPressed: () {
                           if (_formKey.currentState.validate()) {
                             _verifyPhoneNumber(context);
                             uploadPicture(context);
                           }
                         },
                         color: Colors.transparent,
                       ),
                       margin: EdgeInsets.only(
                         top: 30.0,
                         bottom: 30.0,
                       ),
                       decoration: BoxDecoration(
                         color: Colors.transparent,
                         border: Border.all(color: Colors.white, width: 1.0),
                         borderRadius: BorderRadius.circular(10.0),
                       ),
                     ),
                   ],
                 ),
               ),
             ),
           ),
         )
       ],
     );
   }
   _onCreate(String result) {
     widget._scaffold.removeCurrentSnackBar();
     widget._scaffold.showSnackBar(SnackBar(
       content: Text(result),
     ));
     setState(() {
       _submitting = false;
     });
   }
   _onCreateError(dynamic err) {
     widget._scaffold.removeCurrentSnackBar();
     widget._scaffold.showSnackBar(SnackBar(
       content: Text(err),
     ));
     setState(() {
       _submitting = false;
     });
   }

这是用户选择提交的地方,它通过带有打字稿的后端解析提交,此处未显示,但调用了Firebase实例。

   _submit(BuildContext context) async {
     //uploadPicture(context);

     setState(() {
       _submitting = true;
     });
     var newBusiness = new Business();
     newBusiness.businessName = _businessNameController.text;
     newBusiness.businessType = _businessTypeValue;
     newBusiness.phoneNumber = _phoneNumberController.text;
     newBusiness.dob = new DateTime.now();
     newBusiness.lat = _currentLocation.latitude;
     newBusiness.long = _currentLocation.longitude;
     newBusiness.products = _productsController.text.split(',');
     newBusiness.photoUrl = photoURL;
     print("Printing on Submit"+photoURL);
     newBusiness.photoID  = photoID;

    // newBusiness

     BusinessService()
         .createBusiness(newBusiness)
         .then((result) => _onCreate(result))
         .catchError((err) => _onCreateError(err));
   }
   // widget._scaffold.showSnackBar(SnackBar(
   //   content:
   //     Text(_formKey.toString()),
   // ));
   // Exmaple code of how to veify phone number

这是处理电话号码验证,然后调用身份验证器以从Google进行其功能的部分。

   void _verifyPhoneNumber(BuildContext context) async {
     setState(() {
       _message = '';
     });
     final PhoneVerificationCompleted verificationCompleted =
         (AuthCredential user) {
       setState(() {
         _message = 'signInWithPhoneNumber auto succeeded: $user';
       });
     };
     final PhoneVerificationFailed verificationFailed =
         (AuthException authException) {
       setState(() {
         _message =
             'Phone number verification failed. Code: ${authException.code}. Message: ${authException.message}';
       });
     };
     final PhoneCodeSent codeSent =
         (String verificationId, [int forceResendingToken]) async {
       widget._scaffold.showSnackBar(SnackBar(
         content:
             const Text('Please check your phone for the verification code.'),
         duration: new Duration(seconds: 2),
       ));
       _verificationId = verificationId;
     };
     final PhoneCodeAutoRetrievalTimeout codeAutoRetrievalTimeout =
         (String verificationId) {
       _verificationId = verificationId;
     };
     await _auth
         .verifyPhoneNumber(
             phoneNumber: _phoneNumberController.text,
             timeout: const Duration(seconds: 5),
             verificationCompleted: verificationCompleted,
             verificationFailed: verificationFailed,
             codeSent: codeSent,
             codeAutoRetrievalTimeout: codeAutoRetrievalTimeout)
         .then((onValue) => {_showDialog(context)});
   }
   // Example code of how to sign in with phone.
   _signInWithPhoneNumber(BuildContext context) async {
     final AuthCredential credential = PhoneAuthProvider.getCredential(
       verificationId: _verificationId,
       smsCode: _smsController.text,
     );
     try {
       final FirebaseUser user = await _auth.signInWithCredential(credential);
       final FirebaseUser currentUser = await _auth.currentUser();
       assert(user.uid == currentUser.uid);
       setState(() {
         if (user != null) {
           _message = 'Successfully signed in, uid: ' + user.uid;
           _submit(context);
         } else {
           _message = 'Sign in failed';
         }
       });
     } catch (PlatformException) {
       _message = 'Unable to verify your code';
     }
     return context;
   }
   _showDialog(BuildContext context) async {
     // Toast.show("Toast plugin app", context,
     //     duration: Toast.LENGTH_SHORT, gravity: Toast.BOTTOM);
         Fluttertoast.showToast(
           msg: "Toast plugin app",
           toastLength: Toast.LENGTH_SHORT,
           gravity: ToastGravity.BOTTOM
         );
     await showDialog<String>(
         barrierDismissible: false,
         context: context,
         builder: (BuildContext context) {
           return SingleChildScrollView(
             child: new _SystemPadding(
               child: new AlertDialog(
                 contentPadding: const EdgeInsets.all(16.0),
                 title: new Text("Enter the code you just received."),
                 content: new Row(
                   children: <Widget>[
                     new Expanded(
                       child: new TextFormField(
                         controller: _smsController,
                         keyboardType: TextInputType.number,
                         decoration: InputDecoration(labelText: 'Verify Code'),
                         validator: (String value) {
                           if (value.isEmpty || value.toString().length < 6) {
                             return 'Enter 6 digits';
                           }
                         },
                       ),
                     )
                   ],
                 ),
                 actions: <Widget>[
                       new RaisedButton(// cancell function of show dialog 
                     child: Text("Cancel"),
                     onPressed: () async {
                       Navigator.pop(context);
                     },
                     color: Colors.red,
                     textColor: Colors.white,
                     splashColor: Colors.redAccent),
                 new RaisedButton(
                     child: Text("Verify"),
                     onPressed: () async {
                       Navigator.pop(context);
                       await _signInWithPhoneNumber(context);
                     },
                     color: Colors.blue,
                     textColor: Colors.white,
                     splashColor: Colors.blueAccent),
                 ],
               ),
             ),
           );
         });
   }
 }
 class _SystemPadding extends StatelessWidget {
   final Widget child;
   _SystemPadding({Key key, this.child}) : super(key: key);
   @override
   Widget build(BuildContext context) {
     var mediaQuery = MediaQuery.of(context);
     return new AnimatedContainer(
         padding: mediaQuery.viewInsets,
         duration: const Duration(milliseconds: 300),
         child: child);
   }
 }

这是我输入测试电话号码并崩溃时指示的错误的堆栈跟踪

[VERBOSE-2:ui_dart_state.cc(157)] Unhandled Exception: NoSuchMethodError: The method 'existsSync' was called on null.
Receiver: null
Tried calling: existsSync()
#0      Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5)
#1      StorageReference.putFile (package:firebase_storage/src/storage_reference.dart:62:17)
#2      _PhoneSignInSectionState.build.uploadPicture (package:ky/pages/profile_page.dart:133:93)
#3      _AsyncAwaitCompleter.start (dart:async-patch/async_patch.dart:45:6)
#4      _PhoneSignInSectionState.build.uploadPicture (package:ky/pages/profile_page.dart:121:19)
#5      _PhoneSignInSectionState.build.<anonymous closure> (package:ky/pages/profile_page.dart:354:42)
#6      _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:706:14)
#7      _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:789:36)
#8      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24)
#9      TapGestu<…>
        [C6.1 6AAE395C-5E7D-4AC4-99F0-53C557EAF96C 10.20.61.12:62085<->64.233.177.139:443]
        Connected Path: satisfied (Path is satisfied), interface: en0
        Duration: 124.650s, DNS @0.000s took 0.006s, TCP @0.007s took 0.018s, TLS took 0.037s
        bytes in/out: 8761/4752, packets in/out: 33/29, rtt: 0.018s, retransmitted packets: 1, out-of-order packets: 0
Google Maps SDK for iOS cannot connect or validate APIKey: Error Domain=com.google.HTTPStatus Code=400 "(null)" UserInfo={data={length = 145, bytes = 0x3c48544d 4c3e0a3c 48454144 3e0a3c54 ... 3c2f4854 4d4c3e0a }}
Your key may be invalid for your bundle ID:

0 个答案:

没有答案