I am using flutter and firebase for user authentication.
What I am having trouble with is the following segment of code:
import 'package:flutter/material.dart';
class AuthClass {
final FirebaseAuth auth = FirebaseAuth.instance;
//Signing in a user
Future<String> signIn({String email, String password}) async {
try {
await auth.signInWithEmailAndPassword(
email: email,
password: password
);
return "Welcome!";
} on FirebaseAuthException catch (e) {
if (e.code == 'user-not-found') {
return 'No user found for that email.';
} else if (e.code == 'wrong-password') {
return 'Wrong password provided for that user.';
}
}
}
}
The context from which I am calling the signIn function is right here:
import 'package:flutter_client_app/Provider/auth_provider.dart';
import 'package:flutter_client_app/Screens/home.dart';
class LoginPage extends StatefulWidget {
#override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
TextEditingController _email = TextEditingController();
TextEditingController _password = TextEditingController();
bool isLoading = false;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Login"),),
body: isLoading == false ? Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
TextFormField(
controller: _email,
decoration: InputDecoration(
hintText: "Email"
)
),
const SizedBox(height: 30,),
TextFormField(
controller: _password,
decoration: InputDecoration(
hintText: "Password"
)
),
FlatButton( <=============================================================
color: Colors.blue,
onPressed: () {
print (_email.text);
print (_password.text);
setState(() {
isLoading = true;
});
AuthClass()
.signIn(
email: _email.text.trim(),
password: _password.text.trim())
.then((value) {
if (value == "Welcome!") {
setState(() {
isLoading = false;
});
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) => HomePage()),
(route) => false);
} else {
setState(() {
isLoading = false;
});
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text(value)));
}
}); <==============================================================
},
child: Text("Login to account")),
SizedBox(
height: 20,
),
// GestureDetector(
// onTap: () {
// Navigator.pushAndRemoveUntil(
// context,
// MaterialPageRoute(
// builder: (context) => RegisterPage()), (route) => false);
// },
// child: Text("Don't have an account? Register"),
// ),
//
// const SizedBox(
// height: 10,
// ),
// GestureDetector(
// onTap: () {
// Navigator.pushAndRemoveUntil(
// context, MaterialPageRoute(builder: (context) => ResetPage()), (route) => false);
// },
// child: Text("Forgot Password? reset"),
//),
],
),
) : Center(
child: CircularProgressIndicator(),
)
);
}
}
The errors that I am getting are as follows:
29:33: Error: The parameter 'email' can't have a value of 'null' because of its type 'String', but the implicit default value is 'null'.
29:47: Error: The parameter 'password' can't have a value of 'null' because of its type 'String', but the implicit default value is 'null'.
29:18: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
I've been successful in printing out the values that are being recorded in the TextFormField, but my problems spawn when the signIn async function is called.
You are using null-safety feature. You can disable it by change dart sdk in pubspec.yaml to environment: sdk: ">=2.7.0 <3.0.0" instead of environment: sdk: ">=2.12.0 <3.0.0" or make a your class null-safety. Also you should return value for else of if in catch part.
import 'package:flutter/material.dart';
class AuthClass {
final FirebaseAuth auth = FirebaseAuth.instance;
//Signing in a user with nullable parameters
Future<String> signIn({String? email, String? password}) async {
try {
await auth.signInWithEmailAndPassword(
email: email as String,
password: password as String,
);
return "Welcome!";
} on FirebaseAuthException catch (e) {
if (e.code == 'user-not-found') {
return 'No user found for that email.';
} else if (e.code == 'wrong-password') {
return 'Wrong password provided for that user.';
}
else return "No Clear Error"
}
}
//Signing in a user with default value parameters
Future<String> signIn({String email = "", String password = ""}) async {
try {
await auth.signInWithEmailAndPassword(
email: email,
password: password,
);
return "Welcome!";
} on FirebaseAuthException catch (e) {
if (e.code == 'user-not-found') {
return 'No user found for that email.';
} else if (e.code == 'wrong-password') {
return 'Wrong password provided for that user.';
}
else return "No Clear Error"
}
}
}
Related
i am beginner in flutter .
i have a probleme firebase auth with email work on all phones and emulators but on my new samsung phone it doesn't .
here is the error message
/FirebaseAuth( 2571): [FirebaseAuth:] Preparing to create service connection to fallback implementation
W/System ( 2571): Ignoring header X-Firebase-Locale because its value was null.
2
I/System.out( 2571): (HTTPLog)-Static: isSBSettingEnabled false
D/InputMethodManager( 2571): HSIFW - flag : 0
here is my auth screen where the user sign up or login.
import 'package:flutter/material.dart';
import 'package:m51/common/constants.dart';
import 'package:m51/common/loading.dart';
import 'package:m51/services/authentication.dart';
class AuthenticateScreen extends StatefulWidget {
#override
_AuthenticateScreenState createState() => _AuthenticateScreenState();
}
class _AuthenticateScreenState extends State<AuthenticateScreen> {
final AuthenticationService _auth = AuthenticationService();
final _formKey = GlobalKey<FormState>();
String error = '';
bool loading = false;
final emailController = TextEditingController();
final nameController = TextEditingController();
final passwordController = TextEditingController();
bool showSignIn = true;
#override
void dispose() {
nameController.dispose();
emailController.dispose();
passwordController.dispose();
super.dispose();
}
void toggleView() {
setState(() {
_formKey.currentState?.reset();
error = '';
emailController.text = '';
nameController.text = '';
passwordController.text = '';
showSignIn = !showSignIn;
});
}
#override
Widget build(BuildContext context) {
return loading
? Loading()
: Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
backgroundColor: Colors.blueGrey,
elevation: 0.0,
title: Text(showSignIn ? 'Sign in to Water Social' : 'Register to Water Social'),
actions: <Widget>[
TextButton.icon(
icon: Icon(
Icons.person,
color: Colors.white,
),
label: Text(showSignIn ? "Register" : 'Sign In',
style: TextStyle(color: Colors.white)),
onPressed: () => toggleView(),
),
],
),
body: Container(
padding: EdgeInsets.symmetric(vertical: 15.0, horizontal: 30.0),
child: Form(
key: _formKey,
child: Column(
children: [
!showSignIn
? TextFormField(
controller: nameController,
decoration: textInputDecoration.copyWith(hintText: 'name'),
validator: (value) =>
value == null || value.isEmpty ? "Enter a name" : null,
)
: Container(),
!showSignIn ? SizedBox(height: 10.0) : Container(),
TextFormField(
controller: emailController,
decoration: textInputDecoration.copyWith(hintText: 'email'),
validator: (value) =>
value == null || value.isEmpty ? "Enter an email" : null,
),
SizedBox(height: 10.0),
TextFormField(
controller: passwordController,
decoration: textInputDecoration.copyWith(hintText: 'password'),
obscureText: true,
validator: (value) => value != null && value.length < 6
? "Enter a password with at least 6 characters"
: null,
),
SizedBox(height: 10.0),
ElevatedButton(
child: Text(
showSignIn ? "Sign In" : "Register",
style: TextStyle(color: Colors.white),
),
onPressed: () async {
if (_formKey.currentState?.validate() == true) {
setState(() => loading = true);
var password = passwordController.value.text;
var email = emailController.value.text;
var name = nameController.value.text;
dynamic result = showSignIn
? await _auth.signInWithEmailAndPassword(email, password)
: await _auth.registerWithEmailAndPassword(name, email, password);
if (result == null) {
print ('Please supply a valid email');
}
}
}
),
SizedBox(height: 10.0),
Text(
error,
style: TextStyle(color: Colors.red, fontSize: 15.0),
)
],
),
),
),
);
}
}
i also have that message
I/flutter ( 4866): [firebase_auth/invalid-email] The email address is
badly formatted.
the service code
import 'package:firebase_auth/firebase_auth.dart';
import 'package:urjob/models/user.dart';
import 'package:urjob/services/database.dart';
class AuthenticationService {
final FirebaseAuth _auth = FirebaseAuth.instance;
AppUser? _userFromFirebaseUser(User? user) {
return user != null ? AppUser(user.uid) : null;
}
Stream<AppUser?> get user {
return _auth.authStateChanges().map(_userFromFirebaseUser);
}
Future signInWithEmailAndPassword(String email, String password) async {
try {
UserCredential result =
await _auth.signInWithEmailAndPassword(email: email, password: password);
User? user = result.user;
return _userFromFirebaseUser(user);
} catch (exception) {
print(exception.toString());
return null;
}
}
Future registerWithEmailAndPassword(String name, String email, String password, String profilepic) async {
try {
UserCredential result =
await _auth.createUserWithEmailAndPassword(email: email, password: password);
User? user = result.user;
if (user == null) {
throw Exception("No user found");
} else {
await DatabaseService(user.uid).saveUser(name,profilepic,email);
return _userFromFirebaseUser(user);
}
} catch (exception) {
print(exception.toString());
return null;
}
}
Future signOut() async {
try {
return await _auth.signOut();
} catch (exception) {
print(exception.toString());
return null;
}
}
Future sendreset(String email) async {
try {
return await _auth.sendPasswordResetEmail(email: email);
} catch (exception) {
print(exception.toString());
return null;
}
}
}
Thank you for your help
i found the solution
we need in ma case to add .trim() functions to erase white spaces
https://github.com/FirebaseExtended/flutterfire/issues/1760
Trim text gotten from textfields.
emailController.text.trim(),
passwordController.text.trim()
Whenever I tried to do login and tap on the login button then I am having this type of problem with the null check operator used on null values.
This is the error message that I got:
════════ Exception caught by gesture ═══════════════════════════════════════════
The following _CastError was thrown while handling a gesture:
Null check operator used on a null value
When the exception was thrown, this was the stack
#0 _AuthFormState._trySubmit package://FlutterChat/widgets/auth_form.dart:46
#1 _InkResponseState._handleTap
#2 GestureRecognizer.invokeCallback
#3 TapGestureRecognizer.handleTapUp
#4 BaseTapGestureRecognizer._checkUp
Handler: "onTap"
Recognizer: TapGestureRecognizer#c9833
debugOwner: GestureDetector
state: possible
won arena
finalPosition: Offset(165.5, 228.0)
finalLocalPosition: Offset(19.0, 13.5)
button: 1
sent tap down
This is my auth_form.dart file:
import 'package:flutter/material.dart';
import 'dart:io';
import './user_image_picker.dart';
class AuthForm extends StatefulWidget {
AuthForm(this.submitFn, this.isLoading);
final bool isLoading;
final Future<void> Function(String email, String password, String username,
File image, bool isLogin, BuildContext ctx) submitFn;
#override
_AuthFormState createState() => _AuthFormState();
}
class _AuthFormState extends State<AuthForm> {
final _formKey = GlobalKey<FormState>();
var _isLogin = true;
dynamic _userEmail = '';
dynamic _userName = '';
dynamic _userPassword;
File? _userImageFile;
void _pickedImage(File? image) {
_userImageFile = image;
}
//Form validation and save
_trySubmit() {
final isValid = _formKey.currentState?.validate();
FocusScope.of(context).unfocus();
if (_userImageFile == null && !_isLogin) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('Please Select an Image'),
backgroundColor: Theme.of(context).errorColor,
));
return;
}
if (isValid!) {
_formKey.currentState?.save();
widget.submitFn(
_userEmail?.trim(),
_userPassword?.trim(),
_userName?.trim(),
_userImageFile!,
_isLogin,
context,
);
}
}
//Form Widget
#override
Widget build(BuildContext context) {
return new Builder(
builder: (context) {
return Center(
child: Card(
margin: EdgeInsets.all(20),
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(16),
child: Form(
key: _formKey,
child: Column(
children: [
if (!_isLogin) UserImagePicker(_pickedImage),
TextFormField(
key: ValueKey('email'),
autocorrect: false,
textCapitalization: TextCapitalization.none,
enableSuggestions: false,
validator: (value) {
if (value?.isEmpty == null || !value!.contains('#')) {
return 'Please Enter valid Email Address.';
}
return null;
},
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
labelText: 'Email Address',
),
onSaved: (value) {
_userEmail = value;
},
),
if (!_isLogin)
TextFormField(
key: ValueKey('username'),
autocorrect: true,
textCapitalization: TextCapitalization.words,
enableSuggestions: false,
validator: (value) {
if (value!.isEmpty) {
return 'Please Enter Username.';
}
return null;
},
decoration: InputDecoration(
labelText: 'Username',
),
onSaved: (value) {
_userName = value;
}),
TextFormField(
key: ValueKey('password'),
validator: (value) {
if (value?.isEmpty == null || value!.length < 7) {
return 'Password must be atleast 7 characters long';
}
return null;
},
obscureText: true,
decoration: InputDecoration(
labelText: 'Password',
),
onSaved: (value) {
_userPassword = value;
}),
SizedBox(
height: 12,
),
if (widget.isLoading) CircularProgressIndicator(),
if (!widget.isLoading)
ElevatedButton(
child: Text(_isLogin ? 'Login' : 'Signup'),
onPressed: _trySubmit,
),
if (!widget.isLoading)
TextButton(
child: Text(_isLogin
? 'Create a new account'
: 'I already have an account'),
style: TextButton.styleFrom(primary: Colors.pink),
onPressed: () {
setState(() {
_isLogin = !_isLogin;
});
},
),
],
),
),
),
),
),
);
},
);
}
}
This is my auth_screen.dart file:
import 'package:FlutterChat/screens/conversion_screen.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../widgets/auth_form.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'dart:io';
import 'package:firebase_storage/firebase_storage.dart';
//import 'package:firebase_core/firebase_core.dart';
class AuthScreen extends StatefulWidget {
#override
_AuthScreenState createState() => _AuthScreenState();
}
class _AuthScreenState extends State<AuthScreen> {
//FirebaseAuth _auth = FirebaseAuth.instance;
var _isLoading = false;
//Submit AuthCredential Function
Future<void> submitAuthForm(String? email, String? password, String? username,
File? image, bool isLogin, BuildContext ctx) async {
UserCredential userCredential;
try {
setState(() {
_isLoading = true;
});
if (isLogin) {
userCredential = await FirebaseAuth.instance
.signInWithEmailAndPassword(email: email!, password: password!);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ConversionScreen()));
} else {
userCredential = await FirebaseAuth.instance
.createUserWithEmailAndPassword(email: email!, password: password!);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ConversionScreen()));
final ref = FirebaseStorage.instance
.ref()
.child('user_image')
.child(userCredential.user!.uid + '.jpg');
await ref.putFile(image!).whenComplete(() => print('Image Upload'));
final url = await ref.getDownloadURL();
await FirebaseFirestore.instance
.collection('users')
.doc(userCredential.user?.uid)
.set({
'username': username,
'email': email,
'imageUrl': url,
});
}
} on PlatformException catch (error) {
dynamic message = 'An error occured, please check your credentials!';
if (error.message != null) {
message = error.message;
}
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(message),
backgroundColor: Theme.of(ctx).errorColor,
),
);
setState(() {
_isLoading = false;
});
} catch (error) {
print(error);
setState(() {
_isLoading = false;
});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).primaryColor,
body: AuthForm(submitAuthForm, _isLoading),
);
}
}
If someone knows then please help me.
The error is occurring due to this line,
_userImageFile!,
What I suspect is that your if clause,
if (_userImageFile == null && !_isLogin) {
is not protecting it from not being null, since the if clause would be false if _isLogin is true despite _userImageFile being null.
One way to fix this would be to do remove the bang operator since you can also have a case of calling the submitFn when your _isLogin is true and in that case, you definitely won't have a non null _userImageFile.
_userImageFile, // while calling widget.submitFn
Then make sure you change your `submitFn' function type to
final Future<void> Function(String email, String password, String username,
// add the ? for File image
File? image, bool isLogin, BuildContext ctx) submitFn;
Since your, submitAuthForm already says File? image, nothing to change there.
in auth_form.dart,use this process..check the image enter image description here
I am Working on Flutter App Both for web and mobile and stuck at the Following Error:
======== Exception caught by widgets library =======================================================
The following ProviderNotFoundException was thrown building Products(dirty):
Error: Could not find the correct Provider<List<ProductsModel>> above this Products Widget
This happens because you used a `BuildContext` that does not include the provider
of your choice. There are a few common scenarios:
- You added a new provider in your `main.dart` and performed a hot-reload.
To fix, perform a hot-restart.
- The provider you are trying to read is in a different route.
Providers are "scoped". So if you insert of provider inside a route, then
other routes will not be able to access that provider.
- You used a `BuildContext` that is an ancestor of the provider you are trying to read.
Make sure that Products is under your MultiProvider/Provider<List<ProductsModel>>.
This usually happens when you are creating a provider and trying to read it immediately.
For example, instead of:
```
Widget build(BuildContext context) {
return Provider<Example>(
create: (_) => Example(),
// Will throw a ProviderNotFoundError, because `context` is associated
// to the widget that is the parent of `Provider<Example>`
child: Text(context.watch<Example>()),
),
}
```
consider using `builder` like so:
```
Widget build(BuildContext context) {
return Provider<Example>(
create: (_) => Example(),
// we use `builder` to obtain a new `BuildContext` that has access to the provider
builder: (context) {
// No longer throws
return Text(context.watch<Example>()),
}
),
}
```
The relevant error-causing widget was:
Products file:///E:/Flutter%20Projects/flutter_web_firebase_host/lib/screens/home/home.dart:37:63
When the exception was thrown, this was the stack:
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 236:49 throw_
packages/provider/src/provider.dart 332:7 _inheritedElementOf
packages/provider/src/provider.dart 284:30 of
packages/flutter_web_firebase_host/screens/databaseScreens/products.dart 10:31 build
packages/flutter/src/widgets/framework.dart 4569:28 build
...
====================================================================================================
Main.dart
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_web_firebase_host/model/users.dart';
import 'package:flutter_web_firebase_host/provider/product_provider.dart';
import 'package:flutter_web_firebase_host/screens/wrapper.dart';
import 'package:flutter_web_firebase_host/services/auth.dart';
import 'package:flutter_web_firebase_host/services/firestore_service.dart';
import 'package:provider/provider.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) {
final firestoreServise = FirestoreService();
return MultiProvider(
providers: [
ChangeNotifierProvider(
create: (context) => ProductProvider(),
),
StreamProvider(
create: (context) => firestoreServise.getProducts(),
initialData: [],
),
StreamProvider<Users>.value(
value: AuthService().user,
initialData: null,
),
],
/* child: StreamProvider<Users>.value(
value: AuthService().user,
initialData: null*/
child: MaterialApp(
debugShowCheckedModeBanner: false,
home: Wrapper(),
),
);
// );
}
Product.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_web_firebase_host/model/ProductModel.dart';
import 'package:flutter_web_firebase_host/screens/databaseScreens/edit_product.dart';
import 'package:provider/provider.dart';
class Products extends StatelessWidget {
#override
Widget build(BuildContext context) {
final products = Provider.of<List<ProductsModel>>(context, listen: false);
return Scaffold(
appBar: AppBar(
title: Text('Products'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.add),
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => EditProduct()));
}),
],
),
body: (products != null)
? ListView.builder(
itemCount: products.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(products[index].name),
trailing: Text(products[index].price.toString()),
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => EditProduct(products[index])));
},
);
},
)
: Center(child: CircularProgressIndicator()));
}
}
Home.dart
import 'package:flutter/material.dart';
import 'package:flutter_web_firebase_host/screens/databaseScreens/products.dart';
import 'package:flutter_web_firebase_host/services/auth.dart';
import 'package:flutter_web_firebase_host/shared/drawer.dart';
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
final AuthService _auth = AuthService();
#override
Widget build(BuildContext context) {
return Container(
child: Scaffold(
backgroundColor: Colors.brown[100],
appBar: AppBar(
title: Text('Brew Crew'),
backgroundColor: Colors.brown[100],
elevation: 0.0,
actions: <Widget>[
FlatButton.icon(
icon: Icon(Icons.person),
label: Text('logout'),
onPressed: () async {
await _auth.signOut();
},
),
IconButton(
icon: Icon(Icons.add, color: Colors.black),
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => Products()));
}),
],
),
body: SingleChildScrollView(
child: Center(
child: Column(
children: <Widget>[
Container(
child: Padding(
padding: const EdgeInsets.fromLTRB(0.0, 50, 0, 0),
child: Container(
child: Text(
'Stock Market',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
)),
),
),
Container(
child: Padding(
padding: const EdgeInsets.fromLTRB(20, 0, 0, 0),
child: Image.asset(
"assets/graph.jpg",
width: 500,
height: 600,
),
),
),
],
),
),
),
drawer: MyDrawer(),
),
);
}
}
product_provider.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter_web_firebase_host/model/ProductModel.dart';
import 'package:flutter_web_firebase_host/services/firestore_service.dart';
import 'package:uuid/uuid.dart';
class ProductProvider with ChangeNotifier {
final firestoreService = FirestoreService();
String _name;
double _price;
String _productId;
var uuid = Uuid();
//Geters
String get name => _name;
double get price => _price;
//Seters
changeName(String value) {
_name = value;
notifyListeners();
}
changePrice(String value) {
_price = double.parse(value);
notifyListeners();
}
loadValues(ProductsModel product) {
_name=product.name;
_price=product.price;
_productId=product.productId;
}
saveProduct() {
print(_productId);
if (_productId == null) {
var newProduct = ProductsModel(name: name, price: price, productId: uuid.v4());
firestoreService.saveProduct(newProduct);
} else {
//Update
var updatedProduct =
ProductsModel(name: name, price: _price, productId: _productId);
firestoreService.saveProduct(updatedProduct);
}
}
}
Authservise.dart
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter_web_firebase_host/model/users.dart';
import 'package:google_sign_in/google_sign_in.dart';
class AuthService {
final FirebaseAuth _auth = FirebaseAuth.instance;
// create user obj based on firebase user
Users _userFromFirebaseUser(User user) {
return user != null ? Users(uid: user.uid) : null;
}
// auth change user stream
Stream<Users> get user {
return _auth.authStateChanges().map(_userFromFirebaseUser);
}
// sign in anon
Future signInAnon() async {
try {
UserCredential result = await _auth.signInAnonymously();
User user = result.user;
return _userFromFirebaseUser(user);
} catch (e) {
print(e.toString());
return null;
}
}
// sign in with email and password
Future signInWithEmailAndPassword(String email, String password) async {
try {
UserCredential result = await _auth.signInWithEmailAndPassword(email: email, password: password);
User user = result.user;
return user;
} catch (error) {
print(error.toString());
return null;
}
}
// register with email and password
Future registerWithEmailAndPassword(String email, String password) async {
try {
UserCredential result = await _auth.createUserWithEmailAndPassword(email: email, password: password);
User user = result.user;
return _userFromFirebaseUser(user);
} catch (error) {
print(error.toString());
return null;
}
}
// sign out
Future signOut() async {
try {
return await _auth.signOut();
} catch (error) {
print(error.toString());
return null;
}
}
//sign in with google
Future<bool> loginWithGoogle() async {
try {
GoogleSignIn googleSignIn = GoogleSignIn();
GoogleSignInAccount account = await googleSignIn.signIn();
if(account == null )
return false;
UserCredential res = await _auth.signInWithCredential(GoogleAuthProvider.credential(
idToken: (await account.authentication).idToken,
accessToken: (await account.authentication).accessToken,
));
if(res.user == null)
return false;
return true;
} catch (e) {
print(e.message);
print("Error logging with google");
return false;
}
}
}
Basically my app is connect to firebase both for web app and android app. Also i send data to firestore from my app but when i click the add button to go to textfield to send data it give the error as i mention it in start. I am using multiprovider as you can see my main.dart code
Is There anything I missing. I need Help.
the way to fix this is to put MultiProvider as parent of myApp in your main like this
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(
create: (context) => ProductProvider(),
),
StreamProvider(
create: (context) => firestoreServise.getProducts(),
initialData: [],
),
StreamProvider<Users>.value(
value: AuthService().user,
initialData: null,
),
],
child:MyApp(
));
Im having issues trying to get the current user from a child widget. When I login I can see the response if I print from AuthProvider. However, when I try to get the currentUser from a child widget the value is null.
Login in.
Calling query from UsersProvider.
setting the currentUser variable in said provider.
go back to AuthProvider and finish login in the user.
main
#override
Widget build(BuildContext context) {
print('build Main');
return MultiProvider(
providers: [
ChangeNotifierProvider.value(
value: AuthProvider(),
),
ChangeNotifierProvider.value(
value: UsersProvider(),
),
],
child: Consumer<AuthProvider>(
builder: (ctx, auth, _) => MaterialApp(
title: 'Wayuu',
theme: ThemeData(
primarySwatch: Colors.indigo,
accentColor: Colors.purpleAccent,
// textTheme: ThemeData.dark().textTheme.copyWith(
// title: TextStyle(
// color: Theme.of(context).accentColor,
// fontWeight: FontWeight.bold,
// fontSize: 20,
// ),
// ),
),
home: auth.isAuthenticated
? HomeState()
: FutureBuilder(
future: auth.isAuth(),
builder: (ctx, authResultSnapshot) =>
authResultSnapshot.connectionState ==
ConnectionState.waiting
? Splash()
: Login()),
routes: {
Home.routeName: (context) => Home(),
Profile.routeName: (context) => Profile(),
ForgotPassword.routeName: (context) => ForgotPassword(),
RegisterScreen.routeName: (context) => RegisterScreen(),
Favorites.routeName: (context) => Favorites(),
Podcast.routeName: (context) => Podcast(),
MyAccount.routeName: (context) => MyAccount(),
},
),
),
);
}
}
AuthProvider
bool _userAuthenticated = false;
bool get isAuthenticated {
return _userAuthenticated;
}
Future<bool> isAuth() async {
final FirebaseUser response = await FirebaseAuth.instance.currentUser();
if (response != null) {
_userAuthenticated = true;
notifyListeners();
}
return _userAuthenticated;
}
Future<void> loginUser(Map<String, String> loginData) async {
UsersProvider usersProvider = UsersProvider();
try {
final response = await FirebaseAuth.instance.signInWithEmailAndPassword(
email: loginData['usernameOrEmail'], password: loginData['password']);
// _currentUserId = response.user.uid;
await usersProvider.getUserById(response.user.uid);
await storeUserIdInSharePreferences(response.user.uid);
_userAuthenticated = true;
notifyListeners();
} catch (error) {
throw HttpException(error.toString());
}
}
}
UsersProvider
class UsersProvider with ChangeNotifier {
Map<String, dynamic> _currentUser = {};
Map<String, dynamic> get currentUser {
return {..._currentUser};
}
Future<void> getUserById(String userId) async {
try {
QuerySnapshot querySnapshot = await Firestore.instance
.collection('users')
.where('id', isEqualTo: userId)
.getDocuments();
querySnapshot.documents.forEach((documentData) {
_currentUser = {
'id': documentData.data['id'],
'fullName': documentData.data['fullName'],
'email': documentData.data['email'],
'username': documentData.data['username'],
'profilePicture': documentData.data['profilePicture'],
'bio': documentData.data['bio'],
'instagram': documentData.data['instagram'],
'facebook': documentData.data['facebook'],
'web': documentData.data['web']
};
});
notifyListeners();
} catch (error) {
print('error from query');
print(error);
throw HttpException(error.toString());
}
}
}
Profile Widget
Widget build(BuildContext context) {
print('build profile widget');
final currentUser = Provider.of<UsersProvider>(context).currentUser;
print(currentUser);
I get null from here when my "Profile" widget executes
final currentUser = Provider.of<UsersProvider>(context).currentUser;
Thank you in advance !
The instance of UsersProvider that you create inside of loginUser exists only in the scope of that method. Refactor the method to return the response and then use it to update the provider.
var response = await authProvider.loginUser(loginData);
await Provider.of<UsersProvider>(context).getUserById(response.user.uid);
Then when you call the current user it'll be the same instance that will be updated.
Hi Im new in flutter and trying to use firebase phone authentication by using flutter. however, when I try to press the button, I get the following error.
I am using AndroidStudio.
Xcode build done. 21.5s
path: satisfied (Path is satisfied), interface: en0
Configuring the default Firebase app...
Configured the default Firebase app __FIRAPP_DEFAULT.
path: satisfied (Path is satisfied), interface: en0
Syncing files to device iPhone 11 Pro Max...
*** First throw call stack:
(
0 CoreFoundation 0x00007fff23c7127e __exceptionPreprocess + 350
1 libobjc.A.dylib 0x00007fff513fbb20 objc_exception_throw + 48
2 CoreFoundation 0x00007fff23c710bc +[NSException raise:format:] + 188
3 Runner 0x0000000103e97d81 -[FIRPhoneAuthProvider verifyPhoneNumber:UIDelegate:completion:] + 193
4 Runner 0x000000010440dc3d -[FLTFirebaseAuthPlugin handleMethodCall:result:] + 18109
5 Flutter 0x000000010600ddb5 __45-[FlutterMethodChannel setMethodCallHandler:]_block_invoke + 104
6 Flutter 0x0000000105fa1ba0 _ZNK7flutter21PlatformMessageRouter21HandlePlatf<…>
Lost connection to device.
This is my code. Please someone help me
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
// initialRoute: '/',
// routes: {
// '/' : (context) => WelcomeClass(),
// '/LoginClass' : (context) => LoginClass(),
// '/SignUpClass' : (context) => SignUpClass(),
// },
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String phoneNo;
String smsCode;
String verificationId;
Future<void> verifyPhone() async {
final PhoneCodeAutoRetrievalTimeout autoRetrieve = (String verId) {
this.verificationId = verId;
};
final PhoneCodeSent smsCodeSent = (String verId, [int forceCodeResend]) {
this.verificationId = verId;
smsCodeDialog(context).then((value){
print('signed in');
});
};
final PhoneVerificationCompleted verificationSuccess = (AuthCredential user){
print('Phone Verification Completed');
};
final PhoneVerificationFailed verificationFailed =
(AuthException exception) {
print('${exception.message}');
};
await FirebaseAuth.instance.verifyPhoneNumber(
phoneNumber: this.phoneNo,
codeAutoRetrievalTimeout: autoRetrieve,
codeSent: smsCodeSent,
timeout: const Duration(seconds: 60),
verificationCompleted: verificationSuccess,
verificationFailed: verificationFailed,
);
}
Future<bool> smsCodeDialog(BuildContext context) {
return showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return new AlertDialog(
title: Text('Enter sms code'),
content: TextField(
onChanged: (value) {
this.smsCode = value;
},
),
contentPadding: EdgeInsets.all(10),
actions: <Widget>[
FlatButton(
child: Text('Done'),
onPressed: () {
FirebaseAuth.instance.currentUser().then((user) {
if (user != null) {
Navigator.of(context).pop();
Navigator.of(context)
.pushReplacementNamed('/SignUpClass');
} else {
Navigator.of(context).pop();
signIn();
}
});
},
)
],
);
});
}
signIn() {
final AuthCredential credential = PhoneAuthProvider.getCredential(
verificationId: verificationId, smsCode: smsCode);
FirebaseAuth.instance.signInWithCredential(credential).then((user) {
Navigator.of(context).pushReplacementNamed('/homepage');
}).catchError((e) {
print('Auth Credential Error : $e');
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(38.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
TextField(
onChanged: (value) {
this.phoneNo = value;
},
),
SizedBox(
height: 40,
),
FlatButton(
child: Text("Send code"),
onPressed: verifyPhone,
), //FlatButton
], // Widget
),
), // Column
);
}
}
I feel that there is something wrong with the flutter I installed.
Ive also tried to run on my real phone but it crashed too.