Flutter Firebase Auth:出现网络错误(如超时、连接中断或主机不可达)

Posted

技术标签:

【中文标题】Flutter Firebase Auth:出现网络错误(如超时、连接中断或主机不可达)【英文标题】:Flutter Firebase Auth: A network error (such as timeout, interrupted connection or unreachable host) has occurred 【发布时间】: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.。一个因此无法收到短信。

我试过了;

    为我的文件添加如下所示的网络权限(我的互联网连接正常,因为我可以通过模拟器访问 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"/>

    检查我的 API 密钥的有效性

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

    如何消除此错误? 除了缺少 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';
  

【问题讨论】:

【参考方案1】:

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

上允许 Outgoing Connections

【讨论】:

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

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

【讨论】:

【参考方案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 添加到环境变量中。

【讨论】:

以上是关于Flutter Firebase Auth:出现网络错误(如超时、连接中断或主机不可达)的主要内容,如果未能解决你的问题,请参考以下文章

? 应用程序正在运行,但 firebase_auth 和 firebase_core_web 出现错误

Flutter:firebase_auth 好像不行,怎么授权?

flutter-firebase_auth-gradlew.bat 异常退出

评估项目“:firebase_auth”时出现问题

Flutter Firebase Auth 新更新 [重复]

Flutter Firebase auth facebook无法正常工作