I am developing an app in flutter and I'll need to Re Authenticate user but I am getting below error
I/flutter (14968): Error: NoSuchMethodError: The method '[]' was called on null
I/flutter (14968): Receiver: null
I/flutter (14968): Tried calling: []("user")
Below is the code i am using to re authenticate user
FirebaseUser user = await FirebaseAuth.instance.currentUser();
print("User Email: ${user.email}");
AuthCredential authCredential = EmailAuthProvider.getCredential(
email: user.email,
password: _oldPassController.text,
);
print("Auth Credential: ${authCredential.toString()}");
user.reauthenticateWithCredential(authCredential).then((result) {
print("Success: $result");
}).catchError((error) {
print("Error: $error");
setState(() {
_isLoading = false;
});
if (error is PlatformException) {
PlatformException exception = error;
showAlertDialog(context, exception.message);
} else {
showAlertDialog(context, error.toString());
}
});
I don't have a fix for the actual problem (I think it's actually a Firebase-to-Flutter-project connection problem), but I have a workaround that works for me.
I simply use signInWithEmailAndPassword() in place of reauthenticateWithCredential(), and it seems to be working fine. Like so:
AuthResult authResult = await FirebaseAuth.instance
.signInWithEmailAndPassword(email: email, password: password);
FirebaseUser firebaseUser = authResult.user;
After calling the signInWithEmailAndPassword(), the user is re-authenticated because they've recently been logged in.
Hope it's useful.
Related
I'm trying to get the uid, but it always returns the uid of the previously created account.
createUserWithEmailAndPassword does not execute the login after being completed.
So it should be returning the uid correctly, right?
Below are 2 pictures of the database and Authentication, as well as the code.
Future _singUp() async {
final User? user = auth.currentUser;
final uid = user!.uid;
try {
await FirebaseAuth.instance.createUserWithEmailAndPassword(
email: _emailController.text,
password: _passwordController.text,
);
await FirebaseFirestore.instance.collection('users').add({
'email': _emailController.text,
'name': _nameController.text,
'Id_usuario': uid
});
} on FirebaseAuthException catch (e) {
_handleSingUpError(e);
}
}
When you use createUserWithEmailAndPassword it will return a UserCredential as a result, you can use that to update your user variable, so in code it would be something like this:
UserCredential result = await FirebaseAuth.instance.createUserWithEmailAndPassword(email: email, password: password);
User? user = result.user;
I got this code to signup user with email and password in firebase. But the problem is that the try seems doesn't work. It keeps display an exception error message even when I have already put catch there.
static Future<FirebaseUser> signUp(String email, String password) async {
try {
AuthResult result = await _auth.createUserWithEmailAndPassword(
email: email, password: password);
FirebaseUser firebaseUser = result.user;
return firebaseUser;
} catch (e) {
print(e.toString());
return null;
}
}
The error says your email is not properly formatted i.e. it's not matching the username#domain.tld format or is undefined. Try print(email) before the createUserWithEmailAndPassword function and check it.
Also adding an if statement helps:
if (["", null].contains(email)) {
print("Email is null")
}
Validate email in dart might be useful but shouldn't be necessary as Firebase will throw an error is email is not valid.
Today i updated the android emulator i use frecuently and for some reason im getting this error. I already update all possible dependences and packages.
I/FirebaseAuth(11346): [FirebaseAuth:] Preparing to create service connection to fallback implementation
W/System (11346): Ignoring header X-Firebase-Locale because its value was null.
E/flutter (11346): [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: NoSuchMethodError: The getter 'user' was called on null.
E/flutter (11346): Receiver: null
E/flutter (11346): Tried calling: user
E/flutter (11346): #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:54:5)
E/flutter (11346): #1 _RegistrarseState.signupNewUser (package:mundoplay/code/registrarse/registrarse.dart:511:9)
E/flutter (11346): <asynchronous suspension>
This is part of my current code for the user to register:
final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
void signupNewUser(BuildContext context) async {
showDialog(context: context,
barrierDismissible: false,
builder: (BuildContext context)
{
return barraProgreso(mensaje: "Creando su cuenta, espere...",);
});
final firebaseUser = (await _firebaseAuth
.createUserWithEmailAndPassword(
email: email.text, password: password.text)
.catchError((errMsg) {
Navigator.pop(context);
setState(() {
_error = Errors.show(errMsg.code);
});
})).user;
if (firebaseUser != null)
{
Map userDataMap = {
"nombre": nombre.text.trim(),
"apellido": apellido.text.trim(),
"email": email.text.trim(),
"password": password.text.trim(),
"celular": celular.text.trim(),
"direccion": direccion.text.trim(),
"localidad": localidad.text.trim(),
};
usersRef.child(firebaseUser.uid).set(userDataMap).then((value) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString('email', email.text);
//Navigator.push(context, new MaterialPageRoute(builder: (context) => new SeleccionarConsola()));
});
My register and login works with a form with TextEditingControllers that are set to the controller value.
I'm working with the firebase realtime database... any extra info, just ask me and i will try add it. THANKS!
According to the docs, catchError
Returns a new Future that will be completed with either the result of this future or the result of calling the onError callback.
So when you initialize your firebaseUser, you use a catchError that doesn't return nothing (i.e. implicitely returns null). You can see this in practice with a simple example:
Future<T> handleError<T>(Future<T> future) {
return future.catchError((e) {
print("An error occurred.");
// Not returning anything here!
});
}
void main() async {
// When no error occurs, it will print 1
print(await handleError(Future.value(1)));
// When an error occurs, it will print null
print(await handleError(Future.error(Error())));
}
Since you've already said that you're not connected to the internet since you're using an emulator, an error is being thrown inside the future (maybe a "no internet exception" kind of error), the future is returning null and thus the "The getter 'user' was called on null." message.
There are two ways you can avoid this:
Using the ?. operator:
final firebaseUser = (await _firebaseAuth
.createUserWithEmailAndPassword(
email: email.text, password: password.text)
.catchError((errMsg) {
Navigator.pop(context);
setState(() {
_error = Errors.show(errMsg.code);
});
}))?.user; // <- use it here!
Doing it step-by-step:
final result = await _firebaseAuth.createUserWithEmailAndPassword(
email: email.text,
password: password.text,
).catchError((e) {
Navigator.pop(context);
setState(() => _error = Errors.show(errMsg.code));
});
// Early exit
if (result == null) return;
// Only retrieve the firebase user here
final firebaseUser = result.user;
I am trying to set up with apple sign in with the following code. When tapping the button nothing happens.
I get the following error:
Tried calling: authorizationCode
flutter: NoSuchMethodError: The getter 'authorizationCode' was called on null.
Receiver: null
How would I fix this?
Future<bool> get appleSignInAvailable => AppleSignIn.isAvailable();
Future<User> appleSignIn() async {
try {
final AuthorizationResult appleResult =
await AppleSignIn.performRequests([
AppleIdRequest(requestedScopes: [Scope.email, Scope.fullName])
]);
if (appleResult.error != null) {
// handle errors from Apple
}
final AuthCredential credential =
OAuthProvider('apple.com').credential(
accessToken:
String.fromCharCodes(appleResult.credential.authorizationCode),
idToken: String.fromCharCodes(appleResult.credential.identityToken),
);
UserCredential result =
await Global.fbAuth.signInWithCredential(credential);
User user = result.user;
updateUserData(user);
return user;
} catch (error) {
print(error);
return null;
}
}
If you are using iOS 14 simulator, this may be due to the issue reported here. The workaround would be to use a real device for debugging or use the iOS 13 simulator
Also, see this thread for reference
I have faced same kind of issue in one of my projects.You have to add your sha key in firebase and facebook to resolve the issue.
Also you can try the below code,
import 'package:apple_sign_in/apple_sign_in.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/services.dart';
class AuthService {
final _firebaseAuth = FirebaseAuth.instance;
Future<User> signInWithApple({List<Scope> scopes = const []}) async {
// 1. perform the sign-in request
final result = await AppleSignIn.performRequests(
[AppleIdRequest(requestedScopes: scopes)]);
// 2. check the result
switch (result.status) {
case AuthorizationStatus.authorized:
final appleIdCredential = result.credential;
final oAuthProvider = OAuthProvider('apple.com');
final credential = oAuthProvider.credential(
idToken: String.fromCharCodes(appleIdCredential.identityToken),
accessToken:
String.fromCharCodes(appleIdCredential.authorizationCode),
);
final authResult = await _firebaseAuth.signInWithCredential(credential);
final firebaseUser = authResult.user;
if (scopes.contains(Scope.fullName)) {
final displayName =
'${appleIdCredential.fullName.givenName} ${appleIdCredential.fullName.familyName}';
await firebaseUser.updateProfile(displayName: displayName);
}
return firebaseUser;
case AuthorizationStatus.error:
throw PlatformException(
code: 'ERROR_AUTHORIZATION_DENIED',
message: result.error.toString(),
);
case AuthorizationStatus.cancelled:
throw PlatformException(
code: 'ERROR_ABORTED_BY_USER',
message: 'Sign in aborted by user',
);
default:
throw UnimplementedError();
}
}
}
I am trying to save the users who sign in in the firebase database.
this is the function which is used to update the signed in user in the firebase, the fuction uses a uid to create a document with this id :
final Firestore _db = Firestore.instance;
void upadteUserData(FirebaseUser user) async {
DocumentReference ref = _db.collection("users").document(user.uid);
print("in update");
return ref.setData({
"uid": user.uid,
'email': user.email,
'displayName': user.displayName,
//'emergency': []
}, merge: true);
}
and here is the sign in fuction:
Future signInWithEmailAndPassword(String email, String password) async {
try {
AuthResult result = await _auth.signInWithEmailAndPassword(
email: email, password: password);
FirebaseUser user = result.user;
upadteUserData(user);
print("signing in");
print(result.user.email);
return _userFromFirebaseUser(user);
} catch (e) {
print(e.toString());
return null;
}
}
here's the console after signing in
I tried it twice and it was working perfectly fine 3 weeks ago. However, when I try to sign in today with different e-mails, it did not update the fire base. Any idea?