'Flutter Firebase Auth: A network error (such as timeout, interrupted connection or unreachable host) has occurred
I am trying to integrate authentication on Flutter using firebase_auth
.
However, whenever I call the verifyPhoneNumber("+256XXXXXXXXXX")
I get the error message A network error (such as timeout, interrupted connection or unreachable host) has occurred.
, that is from the PhoneVerificationFailed
callback. An for that reason cannot get the SMS.
I have tried;
Adding network permissions as seen below to my file (my internet connection works, as I am able to Google via the emulator)
<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"/>
Checking the validity of my API keys
I am totally confused as to why Flutter is unable to communicate with firebase. I have two questions.
- How can I eliminate this error?
- What other cases might cause this error besides a lacking internet connection?
My implimentatioin is as below;
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';
}
}
Solution 1:[1]
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,
)
],
),
);
}
}
It worked for me, hope this helps you!
Solution 2:[2]
Solution 3:[3]
In my case, my VPN was causing the problem. Disabling the VPN and testing it again solved the error. I hope it helps.
Solution 4:[4]
if you are trying this out in a simulator, then this error may pop up as the internet of your simulator is not connected. To solve this you can run your app on a physical device and it will work!
Solution 5:[5]
Normally when the emulator is doing a lot of work on the thread, it tends to misbehave, such a losing internet connectivity
even if your PC is well connected.
My suggestion(Which worked for me) is you kill the emulator, and go to Android Studio AVD Manager
and Wipe Data
for that Emulator, then restart the Emulator, it worked for me.
Kindly find below the image screenshot
Solution 6:[6]
Open Terminal
in the project folder, run the following two commands:
adb kill-server
adb start-server
If adb
is not recognized, add C:\Users\USERNAME\AppData\Local\Android\Sdk\platform-tools
to environement variables.
Solution 7:[7]
I am late to the party but I found another solution.
If using an android emulator, disabling the Android Studio HTTP proxy settings can restore the network connection.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Dominik |
Solution 2 | Fran Fox |
Solution 3 | NBM |
Solution 4 | Abhiraj Ghosh |
Solution 5 | |
Solution 6 | TiyebM |
Solution 7 | MaximeBeasse |