FirebaseAuth.instance is null - firebase

Hey I'm new to flutter development and I got this message when trying to do SignUp to Firebase
I/flutter (23432): NoSuchMethodError: The method 'createUserWithEmailAndPassword' was called on null.
I/flutter (23432): Receiver: null
And here is the code
AuthServide.dart
class AuthServices {
static FirebaseAuth _auth = FirebaseAuth.instance;
static Future<SignInSignUpResult> signUp(String email, String password,
String name, List<String> selectedGenres, String selectedLanguage) async {
try {
log(_auth.toString());
log("Proses Sign Up");
UserCredential result = await _auth.createUserWithEmailAndPassword(
email: email, password: password);
log("Selesai Sign Up");
log(result.toString());
Users user = result.user.convertToUser(
name: name,
selectedGenres: selectedGenres,
selectedLanguage: selectedLanguage);
await UserServices.updateUser(user);
return SignInSignUpResult(user: user);
} catch (e) {
return SignInSignUpResult(message: e.toString());
}
}
}
After I check the log I know that FirebaseAuth.instance is null, but why?
I'm currently following a tutorial on an online flutter class and I got stuck here.
Anybody can help me?
Thanks

You can try this. I think it will work for you. Make sure you added the firebase auth pakage firebase_auth: ^0.18.4+1
import 'package:firebase_auth/firebase_auth.dart';
class AuthMethods {
// CONDITION ? TRUE: FLASE
User _userFromFirebaseUser(FirebaseUser user) {
return user != null ? User(userId: user.uid) : null;
}
Future signInWithEmailAndPassword(String email, String password) async {
try {
AuthResult result = await _auth.signInWithEmailAndPassword(
email: email, password: password);
FirebaseUser firebaseUser = result.user;
return _userFromFirebaseUser(firebaseUser);
} catch (e) {
print(e.toString());
}
}
try {
AuthResult result = await _auth.createUserWithEmailAndPassword(
email: email, password: password);
FirebaseUser firebaseUser = result.user;
return _userFromFirebaseUser(firebaseUser);
} catch (e) {
print(e.toString());
}
}
Future resetPass(String email) async {
try {
return await _auth.sendPasswordResetEmail(email: email);
} catch (e) {
print(e.toString());
}
}
Future signOut() async {
try {
return await _auth.signOut();
} catch (e) {}
}
}

Related

Can't figure out the error with 'updateProfile' in my flutter code

From the following code i don't know what to do with 'updateProfile' error
signUp() async {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
try {
UserCredential user = await _auth.createUserWithEmailAndPassword(
email: _email, password: _password);
if (user != null) {
[updateProfile][1] updateuser = await _auth.updateProfile();
updateuser.displayName = _name;
user.updateProfile();
}
} catch (e) {
showError(e.message);
print(e);
}
}
}
UserCredential user = await _auth.createUserWithEmailAndPassword(
email: _email, password: _password);
You call the variable 'user' but you set it to UserCredential. updateProfile() is not a function of UserCredential. updateProfile() is not a method of FirebaseAuth either.
Obtain user like this:
User user = (await _auth.createUserWithEmailAndPassword(email: _email, password: _password)).user;

Set state inside auth class?

I have the following problem. I want the message to be the correct exception type. i can only use set state within my sign in (because my auth class is not a statlesswidget)class and pass a message there with set state(), but the same for all errors. I've been trying for 9 hours and I can't figure it out. Please help. so I just want the correct exception to be displayed.Something like „The Email adress is badly formated“.the problem is i it dont let me to set the error message be the real error message and i dont know how to fix it
Widget _buildLoginBtn() {
return Container(
padding: EdgeInsets.symmetric(vertical: 25.0),
width: double.infinity,
child: RawMaterialButton(
elevation: 5.0,
padding: EdgeInsets.all(15.0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0),
),
fillColor: Colors.white,
child: Text(
'LOGIN',
style: TextStyle(
color: Color(0xFF527DAA),
letterSpacing: 1.5,
fontSize: 18.0,
fontWeight: FontWeight.bold,
fontFamily: 'OpenSans',
),
),
onPressed: () async {
if (_formKey.currentState.validate()) {
print('valid');
setState(() => loading = false);
dynamic result =
await _auth.signIN(email, password);
if (result == null) {
setState(() => error = 'Check your Input');
loading= false;
}
}
}),
);
}
Future<String> signIN(String email, String password) async {
try {
FirebaseUser user = (await _auth.signInWithEmailAndPassword(
email: email.trim(), password: password)).user;
} catch (e) {
return null;
}
if (user != null) {
print(user);
}
return null;
}
So after im following # Gerpea advice I Get the following error when im just trying to catch the error without the statement on FIREBASEAUTHERROR and when im trying with the statement. When im trying to update my auth and cloud and core it gets me another error.And I can really say if the he ignored the catch block because it don't starts actually when im starting I get as I said before the error in console Im using:
cupertino_icons: ^1.0.2
firebase_auth: ^0.14.0+5
cloud_firestore: ^0.12.9+4
firebase_core_web: ^0.2.1+3
provider: ^4.3.3
flutter_svg: ^0.19.2+1
flutter_spinkit: "^4.1.2"
auto_size_text: ^2.1.0
firebase_core: ^0.4.0
get_it: ^5.0.6
The error ist this:
Invalid depfile: /Users/MYUSERNAME/Desktop/project neu2/flutter_application_2/.dart_tool/flutter_build/7e96e6ced6aa40f9bcd60c2328bbea3e/kernel_snapshot.d
^
../../../flutter/.pub-cache/hosted/pub.dartlang.org/js-0.6.3/lib/js.dart:8:1: Error: Not found: 'dart:js'
export 'dart:js' show allowInterop, allowInteropCaptureThis;
^
../../../flutter/.pub-cache/hosted/pub.dartlang.org/js-0.6.3/lib/js_util.dart:8:1: Error: Not found: 'dart:js_util'
export 'dart:js_util';
^
../../../flutter/.pub-cache/hosted/pub.dartlang.org/firebase_core_web-0.2.1+3/lib/src/interop/utils/js_interop.dart:24:7: Error: Method not found: 'hasProperty'.
if (util.hasProperty(jsObject, 'toDateString')) {
../../../flutter/.pub-cache/hosted/pub.dartlang.org/firebase_core_web-0.2.1+3/lib/src/interop/utils/utils.dart:39:26: Error: Method not found: 'getProperty'.
map[key] = dartify(util.getProperty(jsObject, key), customDartify);
^^^^^^^^^^^
../../../flutter/.pub-cache/hosted/pub.dartlang.org/firebase_core_web-0.2.1+3/lib/src/interop/utils/utils.dart:65:17: Error: Method not found: 'newObject'.
var jsMap = util.newObject();
../../../flutter/.pub-cache/hosted/pub.dartlang.org/firebase_core_web-0.2.1+3/lib/src/interop/utils/utils.dart:67:7: Error: Method not found: 'setProperty'.
util.setProperty(jsMap, key, jsify(value, customJsify));
../../../flutter/.pub-cache/hosted/pub.dartlang.org/firebase_core_web-0.2.1+3/lib/src/interop/utils/utils.dart:73:12: Error: Method not found: 'allowInterop'.
OKafter trying the second correction that #Gerpea send I get the same error so I decide to update to the newest versions go auth.
No I got some problems but I think that's maybe be easyler to correct
but don't really how maybe you know?
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core_web/firebase_core_web_interop.dart';
import 'package:flutter_application_2/models/user.dart';
class AuthService {
final FirebaseAuth _auth = FirebaseAuth.instance;
String error;
//create user obj based on FirebasedUser
User _userFromFirebaseUser(FirebaseUser user) {
return user != null ? User(uid: user.uid) : null;
}
//auth change user stream
Stream<User> get user {
return _auth.onAuthStateChanged.map(_userFromFirebaseUser);
}
//sign in anon
Future signInAnon() async {
try {
AuthResult result = await _auth.signInAnonymously();
FirebaseUser user = result.user;
return _userFromFirebaseUser(user);
} catch (e) {
print(e.toString());
return null;
}
}
//sign in with passwort and email
Future<String> signIN(String email, String password) async {
try {
FirebaseUser user = (await _auth.signInWithEmailAndPassword(
email: email.trim(),
password: password,
)).user;
} on FirebaseAuthException catch (e) {
switch(e.code) {
case 'user-not-found': {
return 'No user found';
}
default: {
return 'Unexpected error!';
}
}
}
return null;
}
//register with passwort an email
Future<String> signUp(String email, String password) async {
FirebaseUser user = (await _auth.createUserWithEmailAndPassword(
email: email, password: password)) .user;
try {
await user.sendEmailVerification();
return user.uid;
} catch (e) {
print(e.toString);
return null;
}
}
//sign out
Future signOut() async {
try {
return await _auth.signOut();
} catch (e) {
print(e.toString());
return null;
}
}
//resetpassword
Future<void> sendPasswordResetEmail(String email) async {
try {
return await _auth.sendPasswordResetEmail(email: email);
} catch (e) {
print(e.toString());
return null;
}
}
}
that's the exceptions
enter image description here
OK now it logs very good I just have 2 exceptions. Code looks like that:
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter_application_2/models/user.dart' as Model;
class AuthService {
final FirebaseAuth _auth = FirebaseAuth.instance;
String error;
//create user obj based on FirebasedUser
Model.User _userFromFirebaseUser(Model.User user) {
return user != null ? Model.User(uid: user.uid) : null;
}
//auth change user stream
Stream<Model.User> get user {
return _auth.onAuthStateChanged.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 passwort and email
Future<String> signIN(String email, String password) async {
try {
User user = (await _auth.signInWithEmailAndPassword(
email: email.trim(),
password: password,
)).user;
} on FirebaseAuthException catch (e) {
switch(e.code) {
case 'user-not-found': {
return 'No user found';
}
default: {
return 'Unexpected error!';
}
}
}
return null;
}
//register with passwort an email
Future<String> signUp(String email, String password) async {
User user = (await _auth.createUserWithEmailAndPassword(
email: email, password: password)) .user;
try {
await user.sendEmailVerification();
return user.uid;
} catch (e) {
print(e.toString);
return null;
}
}
//sign out
Future signOut() async {
try {
return await _auth.signOut();
} catch (e) {
print(e.toString());
return null;
}
}
//resetpassword
Future<void> sendPasswordResetEmail(String email) async {
try {
return await _auth.sendPasswordResetEmail(email: email);
} catch (e) {
print(e.toString());
return null;
}
}
}
And EXCEptions like that:
enter image description here
#Gerpea
So here's my code
Future<String> signUp(String email, String password, String fullname,String user) async {
try {
( await _auth.createUserWithEmailAndPassword(
email: email.trim(), password: password,)).user.sendEmailVerification();
await DatbaseService(uid: user.uid).updateUserData('username', 'fullname', 'Passwort', 'Email');
} on FirebaseAuthException catch (e) {
And the method from YouTube:
Future registerWithEmailAndAPassword(String email, String,Passwort)async {
try{
AuthResult result = await.createUserWithEmailAndPassowrd(email:email,password:password);
FirebaseUser user =result.user;
await DatabaseService(uid:user.uid).updateUserData('0','new crew member',100);
return _userFromFirebaseUser(user);
}catch (e){
signInWithEmailAndPassword() method in case of error will throw a FirebaseAuthException which contain code field with error code.
The full list of errors for this method can be found here.
So you can rewrite you method a bit, to return an error message instead just null.
Future<String> signIN(String email, String password) async {
try {
User user = (await _auth.signInWithEmailAndPassword(
email: email.trim(),
password: password,
)).user;
} on FirebaseAuthException catch (e) {
switch(e.code) {
case 'user-not-found': {
return 'No user found';
}
default: {
return 'Unexpected error!';
}
}
}
return null;
}
Now this method return null if there is no error and String if some error occurs.
Use this in onPressed callback.
onPressed: () async {
if (_formKey.currentState.validate()) {
print('valid');
String authError = await _auth.signIN(email, password);
if (authError != null) {
setState(() => error = authError);
}
setState(() => loading = false);
}
}
firebase_auth: ^0.14.0+5
This is a bit outdated and has some problems, so it will be better if you
will upgrade your dependencies.
But if you can't upgrade. This should work.
Future<String> signIN(String email, String password) async {
try {
FirebaseUser user = (await _auth.signInWithEmailAndPassword(
email: email.trim(),
password: password,
)).user;
} on AuthException catch (e) {
switch(e.code) {
case 'ERROR_USER_NOT_FOUND': {
return 'No user found';
}
default: {
return 'Unexpected error!';
}
}
} catch(e) {
return 'Some error that FirebaseAuth do not catch'!;
}
return null;
}
List of error codes can be found here.

How to check whether the user email id exists?

I am using the below code for google sign in flutter app with firebase, which is working successfully.
How should I check that whether the email id used is already existing in the firebase authentication?
This I need to ensure that I update the user information in the firestore database accordingly.
Future<User> _handleSignIn() async {
User user;
bool userSignedIn = await _googleSignIn.isSignedIn();
setState(() {
isUserSignedIn = userSignedIn;
});
if (isUserSignedIn) {
user = _auth.currentUser;
}
else {
final GoogleSignInAccount googleUser = await _googleSignIn.signIn();
final GoogleSignInAuthentication googleAuth = await googleUser.authentication;
final AuthCredential credential = GoogleAuthProvider.credential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
user = (await _auth.signInWithCredential(credential)).user;
userSignedIn = await _googleSignIn.isSignedIn();
setState(() {
isUserSignedIn = userSignedIn;
});
}
return user;
}
Please guide me for this
There is a Generic exception related to Firebase Authentication. which is the class FirebaseAuthException. It comes with codes related to errors including email already exists so you would write something like:
try {
//your signIn method here
//i assumed handleSignIn
handleSignIn();
} on FirebaseAuthException catch (e) {
//exception that occurs if e-mail already exists
if (e.code == 'email-already-in-use') {
// the rest of your code here
}
}
Then this is the method you should use I have used to solve my problem
this is my auth.dart file
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:gfd_official/User/User.dart';
import 'package:gfd_official/services/database.dart';
import 'package:google_sign_in/google_sign_in.dart';
String photoUrl;
class AuthService {
final FirebaseAuth _auth = FirebaseAuth.instance;
// create user obj based on firebase user
Userdat _userFromFirebaseUser(User user) {
return user != null ? Userdat(uid: user.uid) : null;
}
// auth change user stream
Stream<Userdat> get user {
return _auth
.authStateChanges()
//.map((FirebaseUser user) => _userFromFirebaseUser(user));
.map(_userFromFirebaseUser);
}
Future signInWithGoogle() async {
GoogleSignIn googleSignIn = GoogleSignIn();
final acc = await googleSignIn.signIn();
final auth = await acc.authentication;
final credential = GoogleAuthProvider.credential(
accessToken: auth.accessToken, idToken: auth.idToken);
try {
final res = await _auth.signInWithCredential(credential);
User user = res.user;
photoUrl = user.photoURL;
UserHelper.saveUser(user);
return _userFromFirebaseUser(user);
} catch (e) {
print(e.toString());
return null;
}
}
Future logOut() {
try {
GoogleSignIn().signOut();
return _auth.signOut();
} catch (e) {
print(e.toString());
return null;
}
}
}
class UserHelper {
static FirebaseFirestore _db = FirebaseFirestore.instance;
static saveUser(User user) async {
Map<String, dynamic> userData = {
"name": user.displayName,
"email": user.email,
"role": "basic",
};
try {
final userRef = _db.collection("users").doc(user.uid);
if ((await userRef.get()).exists) {
await userRef.update({});
} else {
await _db
.collection("users")
.doc(user.uid)
.set(userData, SetOptions(merge: true));
}
} catch (e) {
print(e.toString());
}
}
}
In this the save user function will create database for new user and if user already exist then it will let it remain same as it is.
I am creating a document for every user with his/her uid.

Unhandled Exception: NoSuchMethodError: The getter 'isEmailVerified' was called on null

I am getting the above mentioned error when logging in. This exception is raised even after I am ensuring that the isEmailVerified() is called only after checking whether the current user is null or not.
My authentication.dart file looks like below:
import 'dart:async';
import 'package:firebase_auth/firebase_auth.dart';
abstract class BaseAuth {
Future<String> signIn(String email, String password);
Future<String> signUp(String email, String password);
Future<FirebaseUser> getCurrentUser();
Future<void> sendEmailVerification();
Future<void> signOut();
Future<bool> isEmailVerified();
}
class Auth implements BaseAuth {
final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
Future<String> signIn(String email, String password) async {
AuthResult result = await _firebaseAuth.signInWithEmailAndPassword(
email: email, password: password);
FirebaseUser user = result.user;
return user.uid;
}
Future<String> signUp(String email, String password) async {
AuthResult result = await _firebaseAuth.createUserWithEmailAndPassword(
email: email, password: password);
FirebaseUser user = result.user;
sendEmailVerification();
return user.uid;
}
Future<FirebaseUser> getCurrentUser() async {
FirebaseUser user = await _firebaseAuth.currentUser();
return user;
}
Future<void> signOut() async {
return _firebaseAuth.signOut();
}
Future<void> sendEmailVerification() async {
FirebaseUser user = await _firebaseAuth.currentUser();
user.sendEmailVerification();
}
Future<bool> isEmailVerified() async {
FirebaseUser user = await _firebaseAuth.currentUser();
return user.isEmailVerified;
}
}
And inside the LoginPage, I am checking like this:
if(auth.signIn(email, password)!=null)
{
if(auth.getCurrentUser()!=null)
{
if(auth.isEmailVerified() != null) {
Toast.show("Login Successful!", context, duration: Toast.LENGTH_SHORT, gravity: Toast.BOTTOM);
Route route = MaterialPageRoute(builder: (context) => HomePage());
Navigator.pushReplacement(context, route);
}
}
}
I don't know how to resolve this. Any help is appreciated.
From your Auth class, your methods have future signatures.
You will have to await their results since it will be needed by the other conditions.
You can do:
if((await auth.signIn(email, password))!=null){
if((await auth.getCurrentUser())!=null){
if((await auth.isEmailVerified()) != null) {
Toast.show("Login Successful!", context, duration: Toast.LENGTH_SHORT, gravity: Toast.BOTTOM);
Route route = MaterialPageRoute(builder: (context) => HomePage());
Navigator.pushReplacement(context, route);
}
}
}
But the snippet above must be placed in within an async method.

Firebase.instance.signOut() not setting the currentUser() to null

Why is my signOut() method not setting the currentUser() to null??
When I click on logout on my homepage it checks the isAuthenticated() method which is returning a user instead of null. Also, just have a look at the two comments I've included inside the logout() method.
Thank You!!
Here's my code -
class Auth with ChangeNotifier {
final FirebaseAuth _auth = FirebaseAuth.instance;
final GoogleSignIn _googleSignIn = GoogleSignIn();
bool isAuthenticated() {
print('$currentUser inside the isAuthenticated');
if (currentUser == null) {
print('false');
return false;
}
print('true');
return true;
}
Future<FirebaseUser> get currentUser async {
return await _auth.currentUser();
}
Future<FirebaseUser> signInWithEmail(String email, String password) async {
try {
final response = await _auth.signInWithEmailAndPassword(
email: email,
password: password,
);
print(response);
if (response == null) {
print('response is null');
} else {
notifyListeners();
return response.user;
}
} catch (error) {
print('some error');
throw error;
}
}
Future<FirebaseUser> signInWithGoogle() async {
try {
final GoogleSignInAccount _userDetails = await _googleSignIn.signIn();
if (_userDetails == null) {
print('No user found');
} else {
final GoogleSignInAuthentication googleAuth =
await _userDetails.authentication;
final AuthCredential credential = GoogleAuthProvider.getCredential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
final FirebaseUser user =
(await _auth.signInWithCredential(credential)).user;
return user;
}
notifyListeners();
print('google sign in ran successfully');
} catch (error) {
throw error;
}
}
Future<FirebaseUser> logout() async {
try {
print('logout ran');
print(currentUser); //THIS RETURNS AN INSTANCE OF USER
_auth.signOut().then( (response) {
print('signout successful');
});
await _googleSignIn.signOut();
print(currentUser); //THIS *ALSO* RETURNS AN INSTANCE OF USER
notifyListeners();
return currentUser;
} catch (error) {
print('an error');
}
}
}
I know there would a silly mistake that I'm unable to catch but it's tiring now!! I've tried other methods that I could find on stackoverflow
May be the future is not complete when you try getting current user, have you tried await instead of then in logout?
Future<FirebaseUser> logout() async {
try {
print('logout ran');
print(currentUser); //THIS RETURNS AN INSTANCE OF USER
await _auth.signOut();
await _googleSignIn.signOut();
//The problem is with this, you need to await this
//print(currentUser); //THIS *ALSO* RETURNS AN INSTANCE OF USER
var user = await currentUser;
print(user); //prints null
notifyListeners();
return currentUser;
} catch (error) {
print('an error');
}
}
I faced similar issue and worked it around by assigning null to currentUser. It works fine now!
case R.id.main_logout_option:
updateUserStatus(getString(R.string.strOffline));
mAuth.signOut();
currentUser = null;
goToLoginActivity();
break;

Resources