【问题标题】:Flutter Firebase Auth: A network error (such as timeout, interrupted connection or unreachable host) has occurredFlutter Firebase Auth:出现网络错误(如超时、连接中断或主机不可达)
【发布时间】:2020-06-06 16:03:24
【问题描述】:

我正在尝试使用 firebase_auth 在 Flutter 上集成身份验证。

但是,每当我调用verifyPhoneNumber("+256XXXXXXXXXX") 时,我都会收到来自PhoneVerificationFailed 回调的错误消息A network error (such as timeout, interrupted connection or unreachable host) has occurred.。一个因此无法收到短信。

我试过了;

  1. 为我的文件添加如下所示的网络权限(我的互联网连接正常,因为我可以通过模拟器访问 Google)

    <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

  2. 检查我的 API 密钥的有效性

我完全不明白为什么 Flutter 无法与 firebase 通信。我有两个问题。

  1. 如何消除此错误?
  2. 除了缺少 Internet 连接之外,还有哪些其他情况可能导致此错误?

我的建议如下:

import 'package:firebase_auth/firebase_auth.dart';

FirebaseAuth auth = FirebaseAuth.instance;

var message;
// fire this when Phone verification is completed
 final PhoneVerificationCompleted verificationCompleted =
      (AuthCredential phoneAuthCredential) {
    auth.signInWithCredential(phoneAuthCredential);

    message = 'Received phone auth credential: $phoneAuthCredential';
    print(message);
  };

// fire this when Phone verification fails
  final PhoneVerificationFailed verificationFailed =
      (AuthException authException) {
    message =
        'Phone verification failed. Code: ${authException.code}. Message: ${authException.message}';
    print(message);
  };

  // fire this when SMS code is sent is sent.
  final PhoneCodeSent codeSent =
      (String verificationId, [int forceResendingToken]) async {
    verificationId = verificationId;
    print('Sent verification code');
  };


  // fire this when smsCode expires
  final PhoneCodeAutoRetrievalTimeout codeAutoRetrievalTimeout =
      (String verificationId) {
    verificationId = verificationId;
    print('Auto retrival time-out');
  };

// verify phone number
verifyPhoneNumber(String phoneNumber) {
  auth.verifyPhoneNumber(
      phoneNumber: phoneNumber,
      timeout: const Duration(seconds: 30),
      verificationCompleted: verificationCompleted,
      verificationFailed: verificationFailed,
      codeSent: codeSent,
      codeAutoRetrievalTimeout: codeAutoRetrievalTimeout);
      print('Verification Initiated');
}

// sign in with phone.
signInWithPhoneNumber(String smsCode, String verificationId) async {
  final AuthCredential credential = PhoneAuthProvider.getCredential(
    verificationId: verificationId,
    smsCode: smsCode,
  );

  final FirebaseUser user = (await auth.signInWithCredential(credential)).user;
  final FirebaseUser currentUser = await auth.currentUser();

  assert(user.uid == currentUser.uid);

  if (user != null) {
    message = 'Successfully signed in, uid: ' + user.uid;
  } else {
    message = 'Sign in failed';
  }
}

【问题讨论】:

    标签: firebase flutter dart firebase-authentication


    【解决方案1】:

    在我的情况下,我解决了在 Xcode 的 Runner.xcworkspace

    上允许 Outgoing Connections

    【讨论】:

    • 谢谢,在 Flutter for Desktop (macos) 构建中,默认情况下未选中传出连接。
    【解决方案2】:

    就我而言,是我的 VPN 导致了问题。禁用 VPN 并再次对其进行测试解决了该错误。希望对你有帮助。

    【讨论】:

      【解决方案3】:

      如果您在模拟器中尝试此操作,则可能会在您的模拟器未连接互联网时弹出此错误。要解决这个问题,您可以在物理设备上运行您的应用,它会工作!

      【讨论】:

      • 这个答案对我有帮助。我忽略了这一点。
      【解决方案4】:
      import 'package:badam/varify.dart';
      import 'package:flutter/material.dart';
      import 'package:firebase_auth/firebase_auth.dart';
      import 'dart:async';
      
      import 'HomePage.dart';
      
      void main() => runApp(MyApp());
      
      class MyApp extends StatelessWidget {
        @override
        Widget build(BuildContext context) {
          return MaterialApp(
            debugShowCheckedModeBanner: false,
            title: 'FireBase Demo',
            theme: ThemeData(
              primarySwatch: Colors.blue,
            ),
            home: new LoginPage(),
            routes: <String, WidgetBuilder>{
              '/loginpage' : (BuildContext context) => Dash(),
              '/landpage' : (BuildContext context) => LoginPage(),
          }
          );
        }
      }
      class LoginPage extends StatefulWidget {
        @override
        _LoginPageState createState() => _LoginPageState();
      }
      
      class _LoginPageState extends State<LoginPage> {
        String phoneNo, smsId, verificationId;
      
        Future<void> verifyPhone() async{
          final PhoneCodeAutoRetrievalTimeout autoRetrieve = (String verId){
            this.verificationId = verId;
          };
          final PhoneCodeSent smsCodeSent = (String verId, [int forceCodeResend]){
            this.verificationId = verId;
            smsCodeDialoge(context).then((value){
              print('Signed In');
            });
          };
          final PhoneVerificationCompleted verifiedSuccess = (AuthCredential auth){
            print('verified');
          };
          final PhoneVerificationFailed verifyFailed = (AuthException e) {
            print('${e.message}');
          };
          await FirebaseAuth.instance.verifyPhoneNumber(
            phoneNumber: phoneNo,
            timeout: const Duration(seconds: 5),
            verificationCompleted: verifiedSuccess,
            verificationFailed: verifyFailed,
            codeSent: smsCodeSent,
            codeAutoRetrievalTimeout: autoRetrieve,
          );
        }
        Future<bool> smsCodeDialoge(BuildContext context){
          return showDialog(context: context,
            barrierDismissible: false,
            builder: (BuildContext context) {
              return new AlertDialog(
                title: Text('Enter OTP'),
                content: TextField(
                  onChanged: (value)  {
                    this.smsId  = value;
                  },
                ),
                contentPadding: EdgeInsets.all(10.0),
                actions: <Widget>[
                  new FlatButton(
                      onPressed: (){
                        FirebaseAuth.instance.currentUser().then((user){
                          if(user != null){
                            Navigator.of(context).pop();
                            Navigator.push(
                              context,
                              MaterialPageRoute(builder: (context) => Dash()),
                            );
      
                          }
                          else{
                            Navigator.of(context).pop();
                            signIn(smsId);
                          }
      
                        }
                        );
                      },
                      child: Text('Done', style: TextStyle( color: Colors.blue),))
                ],
              );
            },
          );
        }
      
        Future<void> signIn(String smsCode) async {
          final AuthCredential credential = PhoneAuthProvider.getCredential(
            verificationId: verificationId,
            smsCode: smsCode,
          );
           await FirebaseAuth.instance.signInWithCredential(credential)
              .then((user){
            Navigator.of(context).pushReplacementNamed('/loginpage');
          }).catchError((e){
            print(e);
          });
        }
      
        @override
        Widget build(BuildContext context) {
          return Scaffold(
            appBar: AppBar(
                title: Text('Sign In')
            ),
            body: Column(
              mainAxisAlignment: MainAxisAlignment.center,
      
              children: <Widget>[
                Text('Phone Auth',style: TextStyle(fontSize: 20,color: Colors.blue),),
                Padding(
                  padding: const EdgeInsets.all(16.0),
                  child: TextField(
                    decoration: InputDecoration(
                      hintText: 'Enter your phone number',
                    ),
                    onChanged: (value){
                      this.phoneNo = value;
                    },
                  ),
                ),
                SizedBox(height: 10.0),
                RaisedButton(
                  onPressed: verifyPhone,
                  child: Text('Verify', style: TextStyle(color: Colors.white),),
                  elevation: 7.0,
                  color: Colors.blue,
      
                )
              ],
            ),
          );
        }
      }
      

      它对我有用,希望对你有帮助!

      【讨论】:

        【解决方案5】:

        在项目文件夹中打开Terminal,运行以下两条命令:

        adb kill-server
            
        adb start-server
        

        如果无法识别adb,请将C:\Users\USERNAME\AppData\Local\Android\Sdk\platform-tools 添加到环境变量中。

        【讨论】:

          猜你喜欢
          • 2019-11-03
          • 2022-10-30
          • 2020-04-13
          • 2017-02-24
          • 2021-01-03
          • 2020-01-14
          • 1970-01-01
          • 2021-08-28
          • 2018-01-26
          相关资源
          最近更新 更多