I am a novice to flutter. Mine is a phone verification app.
I am stuck with the following error :Null check operator used on a null value. The complete error message is here: The following _CastError was thrown building Builder:
Null check operator used on a null value
The relevant error-causing widget was: MaterialApp file:///E:/AndroidStudioProjects/phone_verification/lib/main.dart:18:12 When the exception was thrown, this was the stack: #0 _InitializerWidgetState.initState (package:phone_verification/main.dart:48:30) #1 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4711:57) #2 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4548:5) ... Normal element mounting (166 frames) #168 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3611:14)
As I could not solve the issue by the solutions provided here I am posting the question again. Please suggest possible changes in my code. Running on Channel stable. Flutter version is 2.2.3. Thanks
main.dart
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_core/firebase_core.dart' show Firebase;
import 'package:flutter/material.dart';
import 'package:phone_verification/screens/homeScreen.dart';
import 'package:phone_verification/screens/loginScreen.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Phone Verification',
theme: ThemeData(
primarySwatch: Colors.blue,
),
debugShowCheckedModeBanner: false,
home: InitializerWidget(),
);
}
}
class InitializerWidget extends StatefulWidget {
@override
_InitializerWidgetState createState() => _InitializerWidgetState();
}
class _InitializerWidgetState extends State<InitializerWidget> {
late FirebaseAuth _auth;
late User _user;
bool isLoading = true;
@override
void initState() {
// TODO: implement initState
super.initState();
_auth = FirebaseAuth.instance;
_user = _auth.currentUser!;
bool isLoading = false;
}
@override
Widget build(BuildContext context) {
return isLoading ? Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
) : _user == null ? LoginScreen() : HomeScreen();
}
}
loginScreen.dart
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:phone_verification/screens/homeScreen.dart';
enum MobileVerificationState {
SHOW_MOBILE_FORM_STATE,
SHOW_OTP_FORM_STATE,
}
class LoginScreen extends StatefulWidget {
@override
_LoginScreenState createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
MobileVerificationState currentState = MobileVerificationState.SHOW_MOBILE_FORM_STATE;
final phoneController = TextEditingController();
final otpController = TextEditingController();
FirebaseAuth _auth = FirebaseAuth.instance;
late String verificationId;
bool showLoading = false;
void signInWithPhoneAuthCredential(PhoneAuthCredential phoneAuthCredential) async {
setState(() {
showLoading = true;
});
try {
final authCredential = await _auth.signInWithCredential(phoneAuthCredential);
setState(() {
showLoading = false;
});
if(authCredential.user != null)
{
Navigator.push(context,MaterialPageRoute(builder: (context)=> HomeScreen()));
}
}on FirebaseAuthException catch (e) {
setState(() {
showLoading = false;
});
_scaffoldKey.currentState!.showSnackBar(SnackBar(content: Text(e.message.toString())));
}
}
getMobileFormWidget(context) {
return Column(
children: [
Spacer(),
TextField(
controller: phoneController,
decoration: InputDecoration(hintText: "Phone Number"),
),
SizedBox(
height: 16.0,
),
SizedBox(
width: 10.0,
),
TextButton(
onPressed: ()async {
setState(() {
showLoading = true;
});
await _auth.verifyPhoneNumber(
phoneNumber: phoneController.text,
verificationCompleted: (phoneAuthCredential) async {
setState(() {
showLoading = false;
});
//signInWithPhoneAuthCredential(phoneAuthCredential);
},
verificationFailed: (verificationFailed) async {
setState(() {
showLoading = false;
});
_scaffoldKey.currentState!.showSnackBar(SnackBar(content: Text(verificationFailed.message.toString())));
},
codeSent: (verificationId, resendingToken) async {
setState(() {
showLoading = false;
currentState = MobileVerificationState.SHOW_OTP_FORM_STATE;
this.verificationId = verificationId;
});
},
codeAutoRetrievalTimeout: (verificationId) async {
},
);
},
child: Text(
"SEND",
),
style: TextButton.styleFrom(
primary: Colors.white,
backgroundColor: Colors.deepPurple,
),
),
Spacer(),
],
);
}
getOtpFormWidget(context) {
return Column(
children: [
Spacer(),
TextField(
controller: otpController,
decoration: InputDecoration(hintText: "Enter OTP"),
),
SizedBox(
height: 16.0,
),
SizedBox(
width: 10.0,
),
TextButton(
onPressed: () async {
PhoneAuthCredential phoneAuthCredential =
PhoneAuthProvider.credential(verificationId: verificationId, smsCode: otpController.text);
signInWithPhoneAuthCredential(phoneAuthCredential);
},
child: Text(
"VERIFY",
),
style: TextButton.styleFrom(
primary: Colors.white,
backgroundColor: Colors.deepPurple,
),
),
Spacer(),
],
);
}
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey();
@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
body: Container(
child: showLoading ? Center(child: CircularProgressIndicator(),) : currentState == MobileVerificationState.SHOW_MOBILE_FORM_STATE
? getMobileFormWidget(context)
: getOtpFormWidget(context),
padding: const EdgeInsets.all(16),
));
}
}
homeScreen.dart
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:phone_verification/screens/loginScreen.dart';
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
final _auth = FirebaseAuth.instance;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text("Home Screen"),
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
await _auth.signOut();
Navigator.pushReplacement(context,MaterialPageRoute(builder: (context) => LoginScreen()));
},
child: Icon(Icons.logout),
),
);
}
}