How to get data from the CurrentUser on flutter Firebase Authentification - flutter

I have this Firebase Authentication Providers with who I can create an user, Sign In and Sign Out with the methods (only with email and password)
My problem I that in the UI I want to show data from the current User once the user has Sign In and I don't know how.
For example showing the email in a TextWidget or get the email as a variable for other stuff.
final firebaseAuthProvider = Provider<FirebaseAuth>((ref) {
return FirebaseAuth.instance;
});
class AuthenticationService {
final FirebaseAuth _firebaseAuth;
final Reader read;
AuthenticationService(this._firebaseAuth, this.read);
Stream<User?> get authStateChange => _firebaseAuth.authStateChanges();
Future<String> signIn({required String email, required String constrasena, required String nombreUsuario}) async {
try {
await _firebaseAuth.signInWithEmailAndPassword(
email: email,
password: constrasena,
);
return "Login Successful";
} on FirebaseAuthException catch (e) {
return e.message ?? 'Error';
}
}
Future<String> signUp({required String email, required String constrasena, required String nombreUsuario}) async {
try {
await _firebaseAuth.createUserWithEmailAndPassword(
email: email,
password: constrasena,
);
read(addPerson(Person(nombre_de_usuario: nombreUsuario, email: email, videosVistos: 0)));
return "Signup Successful";
} on FirebaseAuthException catch (e) {
print(e.message);
return e.message ?? 'Error';
}
}
Future<void> signout() async {
await _firebaseAuth.signOut();
}
}
final authServicesProvider = Provider<AuthenticationService>((ref) {
return AuthenticationService(ref.read(firebaseAuthProvider), ref.read);
});
final authStateProvider = StreamProvider<User?>((ref) {
return ref.watch(authServicesProvider).authStateChange;
});
Thanks You!

You can use FirebaseAuth.instance.currentUser.
Example:
Get the user on your initState.
_user = FirebaseAuth.instance.currentUser;
And on your build method:
Text(_user?.email ?? 'No email')

Related

Create an user in Firebase without automatically login

I have wrote a code, which should avoid the automatically login when an user get created.
The code worked until I used the dart migration tool. Now when I use this code with null-safety, then the secondaryApp is not created and another user get logged in.
Can someone please explain me, what I am doing wrong? I need to fix this code as fast as possible, but I just can't find the mistake.
I really appreciate any help.
code login:
InkWell(
onTap: () async {
await authProvider.signUpUser(
usernameController.text.trim(),
emailController.text.trim(),
passwordController.text.trim(),
firstNameController.text.trim(),
lastNameController.text.trim(),
_birthDateInString,
_genderSelected);
})
code (database request):
Future<bool> signUpUser(String username, String email, String password,
String firstName, String lastName, String? birthday, String? gender) async {
try {
_status = Status.Authenticating;
notifyListeners(); //changing status
FirebaseApp secondaryApp = await Firebase.initializeApp(
name: 'Secondary',
options: Firebase.app().options,
);
try {
UserCredential? credential = await FirebaseAuth.instanceFor(
app: secondaryApp)
.createUserWithEmailAndPassword(email: email, password: password)
.then((result) async {
//User user = result.user;
_userServices.createUser(
uid: result.user!.uid,
username: username,
email: email,
firstName: firstName,
lastName: lastName,
birthday: birthday,
gender: gender,
status: 'aktiv',
role: 'User',
);
});
print('user created');
await credential?.user!.sendEmailVerification();
} on FirebaseAuthException catch (e) {
print(e);
}
print('secondapp deleted');
await secondaryApp.delete();
_status = Status.Unauthenticated;
notifyListeners();
print('secondapp deleted');
return true;
} catch (e) {
_status = Status.Unauthenticated;
notifyListeners();
print(e.toString());
return false;
}
}
A little difficult to completely debug your project without a little more context but I tried to clean up just a bit and add a few print statements to help you out, hope this helps :)
Future<bool> signUpUser(
String username,
String email,
String password,
String firstName,
String lastName,
String? birthday,
String? gender,
) async {
try {
_status = Status.Authenticating;
notifyListeners(); //changing status
FirebaseApp secondaryApp = await Firebase.initializeApp(
name: 'Secondary',
options: Firebase.app().options,
);
/// here is our user:)
var _user;
try {
UserCredential? credential = await FirebaseAuth.instanceFor(app: secondaryApp)
.createUserWithEmailAndPassword(email: email, password: password);
print('we got our credentials lets take a look to see if we have them ${credential}');
var uid = credential.user?.uid;
if (uid != null) {
_userServices.createUser(
uid: uid,
username: username,
email: email,
firstName: firstName,
lastName: lastName,
birthday: birthday,
gender: gender,
status: 'aktiv',
role: 'User',
);
print('user created');
}
_user = credential?.user;
if (_user != null) {
await credential?.user.sendEmailVerification();
print('done with our send email verification!');
}
} on FirebaseAuthException catch (e) {
print(e);
}
if (_user != null) {
/// this means that we successfully authenticated our user consider returning from the function right here!!
}
print('secondapp deleted');
await secondaryApp.delete();
_status = Status.Unauthenticated;
notifyListeners();
print('secondapp deleted');
return true;
} catch (e) {
_status = Status.Unauthenticated;
notifyListeners();
print(e.toString());
return false;
}
}
One other thing that I noticed with your code is that if a User successfully authenticates then you automatically delete your secondaryApp. Is this your desired behavior?
I went ahead and added a note for you to add some code in there if you want but didn't want to dramatically change your code.

Flutter : How to use Email Verification FIrebase Auth

I just finished Firebase Auth for my first application, but I want to add Email Verification when the user has Sign Up, please how can I make it.
class AuthServices {
final auth.FirebaseAuth _firebaseAuth = auth.FirebaseAuth.instance;
Login? _userFromFirebase(auth.User? user) {
if (user == null) {
return null;
}
return Login(user.uid, user.email);
}
Stream<Login?>? get user {
return _firebaseAuth.authStateChanges().map(_userFromFirebase);
}
Future<Login?> signUp(String email, String password, String name) async {
final credential = await _firebaseAuth.createUserWithEmailAndPassword(
email: email, password: password);
UserService().createUser(name);
return _userFromFirebase(credential.user);
}
Future<Login?> signIn(String email, String password) async {
final credential = await _firebaseAuth.signInWithEmailAndPassword(
email: email, password: password);
return _userFromFirebase(credential.user);
}
Future<void> signOut() async {
return await _firebaseAuth.signOut();
}
}
This will do your job:-
final firebaseUser = await FirebaseAuth.instance
.signInWithEmailAndPassword(email: email, password: password);
if (firebaseUser.isEmailVerified){
//Verified
}
else {
firebaseUser.sendEmailVerification();
}
Future<Login?> signUp(String email, String password, String name) async {
final credential = await _firebaseAuth.createUserWithEmailAndPassword(
email: email, password: password);
await credential.user?.sendEmailVerification(); // Add this line
UserService().createUser(name);
return _userFromFirebase(credential.user);
}

Flutter | Getting Firebase Email Link Login Data

I have difficulty implementing the Email Link login with Firebase.
I send the email link using:
_firebaseAuth.sendSignInLinkToEmail(
email: email,
actionCodeSettings: ActionCodeSettings(
url: 'https://subdomain.example.com/user-auth', //<subdomain.example.com> = my real domain
handleCodeInApp: true,
androidInstallApp: true,
androidPackageName: 'com.example.app',
),
);
Email is sent and when clicking I open the link using the DynamicLink package:
void _handleDynamicLinks() {
FirebaseDynamicLinks.instance.onLink(onSuccess: _onSuccess);
}
Future<dynamic> _onSuccess(PendingDynamicLinkData data) async {
print('---onLink---');
// How to pass signIn link to `isSignInWithEmailLink` and `signInWithEmailLink` ???
// data.link returns `https://subdomain.example.com/user-auth` which is not the complete link
}
Every method I call on PendingDynamicLinkData data doesn't return the full dynamic link and isSignInWithEmailLink returns false!
Try this in your _handleDynamicLink function.
try {
FirebaseDynamicLinks.instance.onLink.listen((dynamicLink) {
final Uri? deepLink = dynamicLink.link;
if (deepLink != null) {
emailLinkService.handleLink(deepLink, _emailController.text);
FirebaseDynamicLinks.instance.onLink.listen((dynamicLink) {
final Uri? deepLink = dynamicLink.link;
emailLinkService.handleLink(deepLink!, _emailController.text);
}, onError: (e) async {
print(e.message);
});
}
}, onError: (e) async {
print(e.message);
});
final PendingDynamicLinkData? data =
await FirebaseDynamicLinks.instance.getInitialLink();
final Uri? deepLink = data?.link;
print('deepLink :: $deepLink');
} catch (e) {
// you can print this error as well
}
And check if your url is the same as here:
And also add the Dynamic link as your custom Authorised domain like this:
Here is the handleLink method:
class EmailLinkService {
final FirebaseAuth _auth = FirebaseAuth.instance;
Future<void> signInWithEmailAndLink(
{required String userEmail}) async {
var _userEmail = userEmail;
var acs = ActionCodeSettings(
url: Constants.firebaseProjectURL,
handleCodeInApp: true,
iOSBundleId: 'com.example....',
androidPackageName: 'com.example....',
try {
return await _auth
.sendSignInLinkToEmail(email: _userEmail, actionCodeSettings: acs);
} on FirebaseAuthException catch (e) {
}
void handleLink(Uri link, userEmail) async {
if (link != null) {
final UserCredential user =
await FirebaseAuth.instance.signInWithEmailLink(
email: userEmail,
emailLink: link.toString(),
);
} else {
print(" link is null");
}
}
}

Flutter how to listen for email verification before user can sign in - firebase

My app allows the user to register and sends an email for verification. However i have a problem where the user can sign in with the new account whether the email is verified or not. I have looked and cannot find a solution to this bearing in mind i'm new to flutter
My Auth Code
Future<String> signIn(String email, String password) async {
AuthResult result = await _firebaseAuth.signInWithEmailAndPassword(
email: email, password: password);
FirebaseUser user = result.user;
if (user.isEmailVerified) {
return user.uid;
} else {
return null;
}
}
Future<String> signUp(String email, String password) async {
AuthResult result = await _firebaseAuth.createUserWithEmailAndPassword(
email: email, password: password);
FirebaseUser user = result.user;
try {
await user.sendEmailVerification();
return user.uid;
} catch (e) {
print("An error occurred while trying to send email verification");
print(e.message);
}
}
sign in method
try {
if (_isLoginForm) {
userId = await widget.auth.signIn(_email, _password);
print('Signed in: $userId');
} else {
userId = await widget.auth.signUp(_email, _password);
//widget.auth.sendEmailVerification();
_showVerifyEmailSentDialog();
print('Signed up user: $userId');
}
setState(() {
_isLoading = false;
});
if (userId.length > 0 && userId != null && _isLoginForm) {
widget.loginCallback();
}

Flutter, firebase. I want to show my registration form data other than the email and password and connect to a unique uid

Register Screen On Pressed method given, I believe there is a problem with calling Firebase user = result.user
onPressed: () async {
if(_formKey.currentState.validate()){
setState(() => loading = true);
dynamic result = await _auth.registerWithEmailAndPassword(email, password);
FirebaseUser user = result.user;
await DatabaseService(uid: user.uid).newUserInfo(
_nameC.text,
_cityC.text,
_contactnoC.toString()
);
if(result == null) {
setState(() {
error = 'Please supply a valid email';
loading = false;
});
}}},
// Database backend
class DatabaseService {
final String uid;
DatabaseService ({this.uid});
final CollectionReference userdata2 = Firestore.instance.collection('UserData');
Future newUserInfo(String name, String city, String contactno) async {
return await userdata2.document(uid).setData({
'name' : name,
'city' : city,
'contactno' : contactno
});
}}
// authentication backend
// register with email and password
Future registerWithEmailAndPassword(String email, String password) async {
try {
AuthResult result = await _auth.createUserWithEmailAndPassword(email: email, password: password);
FirebaseUser user = result.user;
DatabaseService(uid: user.uid);
return _userFromFirebaseUser(user);
} catch (error) {
print(error.toString());
return null;
} }
// user.dart
class User {
final String uid;
User({this.uid});
}