How to pass uid and email to sharedpreference method When signUp in flutter? - flutter

I built the google signin and email password signup app using flutter,
I want when user log to application then user's "uid" and "email" save in shared preference.
In google login I built when login then pass the boolean value and pass uid and email to shared preference. Then when users close app and when reopen then login in home screen and can get uid and email.
But when user signup or login using email password then can not pass the boolean value and uid and email to google login shared preference. In below I'll mentioned google login method and email password method.
googlelogin method
// handling google sigin in
Future handleGoogleSignIn() async {
final sp = context.read<SignInProvider>();
final ip = context.read<InternetProvider>();
await ip.checkInternetConnection();
if (ip.hasInternet == false) {
openSnackbar(context, 'Check your Internet connection', Colors.red);
googleController.reset();
} else {
await sp.signInWithGoogle().then((value) {
if (sp.hasError == true) {
openSnackbar(context, sp.errorCode.toString(), Colors.white);
googleController.reset();
} else {
// checking whether user exists or not
sp.checkUserExists().then((value) async {
if (value == true) {
// user exists
await sp.getUserDataFromFirestore(sp.uid).then((value) => sp
.saveDataToSharedPreferences()
.then((value) => sp.setSignIn().then((value) {
googleController.success();
handleAfterSignIn();
})));
} else {
// user does not exist
sp.saveDataToFirestore().then((value) => sp
.saveDataToSharedPreferences()
.then((value) => sp.setSignIn().then((value) {
googleController.success();
handleAfterSignIn();
})));
}
});
}
});
}
//login function
}
saveDataToSharedPreferences method and setSignIn boolean value (it has in a siginprovider class in another file)
class SignInProvider extends ChangeNotifier {
//instantiate of firebaseAuth, facebook and google
final FirebaseAuth firebaseAuth = FirebaseAuth.instance;
final GoogleSignIn googleSignIn = GoogleSignIn();
bool _isSignedIn = false;
bool get isSignedIn => _isSignedIn;
//hasError, errorCode, provider,uid,email,name,imageUrl
bool _hasError = false;
bool get hasError => _hasError;
String? _errorCode;
String? get errorCode => _errorCode;
String? _uid;
String? get uid => _uid;
String? _email;
String? get email => _email;
SignInProvider() {
checkSignInUser();
}
Future checkSignInUser() async {
final SharedPreferences s = await SharedPreferences.getInstance();
_isSignedIn = s.getBool('signed_in') ?? false;
notifyListeners();
}
Future setSignIn() async {
final SharedPreferences s = await SharedPreferences.getInstance();
s.setBool('signed_in', true);
_isSignedIn = true;
notifyListeners();
}
Future saveDataToSharedPreferences() async {
final SharedPreferences s = await SharedPreferences.getInstance();
await s.setString('email', _email!);
await s.setString('uid', _uid!);
notifyListeners();
}
Future getDataFromSharedPreferences() async {
final SharedPreferences s = await SharedPreferences.getInstance();
_email = s.getString('email');
_uid = s.getString('uid');
notifyListeners();
}
}
**email password signup**
void signUp(String email, String password) async {
if (_formkey.currentState!.validate()) {
await _auth
.createUserWithEmailAndPassword(email: email, password: password)
.saveDataToSharedPreferences()
.sp.setSignIn()
.then((value) => {postDetailsToFirestore()})
.catchError((e) {
Fluttertoast.showToast(msg: e!.message);
});
}
}
in email password signup has postDetailsToFirestore method
postDetailsToFirestore() async {
// calling our fireStore
//calling our user model
// sending these values
FirebaseFirestore firebaseFirestore = FirebaseFirestore.instance;
User? user = _auth.currentUser;
UserModel userModel = UserModel();
if (user != null) {
//writing all the values
userModel.email = user?.email;
userModel.uid = user?.uid;
await firebaseFirestore
.collection("users")
.doc(user?.uid)
.set(userModel.toMap());
Fluttertoast.showToast(msg: "Account created successfully ");
Navigator.pushAndRemoveUntil(
(context),
MaterialPageRoute(builder: (context) => HomeScreen()),
(route) => false);
}
}
in email password signup I called
these 2 methods but show this error
when signup how to pass uid and emaill to saveDataToSharedPreferences method and pass sp.setSignIn() boolean like as in google signing?

You are trying to use method saveDataToSharedPreferences from Future class, not from auth. For fix this issue, call prefs from main object:
final result = await _auth.createUserWithEmailAndPassword(
email: email,
password: password,
);
result.saveDataToSharedPreferences()
.sp.setSignIn()
// etc.

Related

Flutter Getx: google signin and map data to firebase automatically logs me back in as same user?

I am trying to login with google and have the data mapped to a firebase user. I'm using getX. So far this works HOWEVER it automatically logs me back in as the same user if I logout and then try to log back in again. I'll send the code for my login page and the page where the logout button is if needed, but I suspect this may have to do with my AuthController which I've included here
class AuthController extends GetxController {
static AuthController instance = Get.find();
GoogleSignIn googleSignIn = GoogleSignIn();
Rxn<User> firebaseUser = Rxn<User>();
Rxn<UserModel> firestoreUser = Rxn<UserModel>();
final RxBool admin = false.obs;
String usersCollection = "users";
#override
void onReady() async {
//run every time auth state changes
ever(firebaseUser, handleAuthChanged);
firebaseUser.bindStream(user);
super.onReady();
}
handleAuthChanged(firebaseUser) async {
//get user data from firestore
if (firebaseUser?.uid != null) {
firestoreUser.bindStream(streamFirestoreUser());
print("You are logged in as ${firebaseUser.email}");
await isAdmin();
}
//this is for new users
if (firebaseUser == null) {
print('Send to signin');
Get.offAll(LoginPage());
} else {
Get.offAll(AppSetup());
}
}
// Firebase user one-time fetch
Future<User> get getUser async => auth.currentUser!;
// Firebase user a realtime stream
Stream<User?> get user => auth.authStateChanges();
//Streams the firestore user from the firestore collection
Stream<UserModel> streamFirestoreUser() {
print('streamFirestoreUser()');
return firebaseFirestore
.doc('/users/${firebaseUser.value!.uid}')
.snapshots()
.map((snapshot) => UserModel.fromSnapshot(snapshot));
}
//get the firestore user from the firestore collection
Future<UserModel> getFirestoreUser() {
return firebaseFirestore
.doc('/users/${firebaseUser.value!.uid}')
.get()
.then((documentSnapshot) => UserModel.fromSnapshot(documentSnapshot));
}
//Method to handle user sign in using email and password
// User registration using email and password
googleLogin(BuildContext context) async {
final GoogleSignInAccount? googleUser = await googleSignIn.signIn();
if (googleUser != null) {
final googleAuth = await googleUser.authentication;
if (googleAuth.accessToken != null && googleAuth.idToken != null) {
try {
await auth
.signInWithCredential(
GoogleAuthProvider.credential(
idToken: googleAuth.idToken,
accessToken: googleAuth.accessToken),
)
.then((firebaseUser) async {
print('uid: ' + firebaseUser.user!.uid.toString());
print('email: ' + firebaseUser.user!.email.toString());
//create the new user object from the login modelled data
UserModel _newUser = UserModel(
id: firebaseUser.user!.uid,
email: firebaseUser.user!.email!,
name: firebaseUser.user!.email!,
photoURL: firebaseUser.user!.photoURL,
cart: [],
);
//create the user in firestore here with the _addUserToFirestore function
_updateUserFirestore(_newUser, firebaseUser.user!);
});
} on FirebaseAuthException catch (error) {
Get.snackbar('auth.signUpErrorTitle'.tr, error.message!,
snackPosition: SnackPosition.BOTTOM,
duration: Duration(seconds: 10),
backgroundColor: Get.theme.snackBarTheme.backgroundColor,
colorText: Get.theme.snackBarTheme.actionTextColor);
}
}
}
}
void _updateUserFirestore(UserModel user, User _firebaseUser) {
firebaseFirestore.doc('/users/${_firebaseUser.uid}').update(user.toJson());
update();
}
updateUserData(Map<String, dynamic> data) {
logger.i("UPDATED");
firebaseFirestore
.collection(usersCollection)
.doc(firebaseUser.value!.uid)
.update(data);
}
//check if user is an admin user
isAdmin() async {
await getUser.then((user) async {
DocumentSnapshot adminRef =
await firebaseFirestore.collection('admin').doc(user.uid).get();
if (adminRef.exists) {
admin.value = true;
} else {
admin.value = false;
}
update();
});
}
// This is the proper sign out method!
Future<void> signOut() {
return auth.signOut();
}
}
Simply add this line of code into your logout function
> await googleSignIn.signOut()

How to retrieve current user data from firebase?

I tried this way, but i'm getting an error.
The error:
The method 'data' isn't defined for the type 'CollectionReference'. (undefined_method at [myapp] android\app\lib\useracc.dart:32)
void getData() async{
User? user = await FirebaseAuth.instance.currentUser;
var vari =FirebaseFirestore.instance.collection("users");
setState (() {
name = vari.data()['firstname'];
}
);
}
Signup/Register Page
Future<User?> _register(String fname,String lname ,String email, String password) async{
FirebaseAuth _auth = FirebaseAuth.instance;
FirebaseFirestore _firestore = FirebaseFirestore.instance;
try {
UserCredential userCrendetial = await _auth.createUserWithEmailAndPassword(email: emailController.text, password: passwordController.text);
print("Account created Succesfull");
userCrendetial.user!.updateDisplayName(fname);
userCrendetial.user!.updateDisplayName(lname);
await _firestore.collection('users').doc(_auth.currentUser!.uid).set({
"firstname": fname,
"lastname" : lname,
"email": email,
"uid": _auth.currentUser!.uid,
});
return userCrendetial.user;
} catch (e) {
print(e);
return null;
}
}
This is the user account from where i want to fetch info:
Please help. I'm struck here a long time.
You should retrieve the currentUser document then access its data:
void getData() async{
var vari = await FirebaseFirestore.instance
.collection("users")
.doc(FirebaseAuth.instance.currentUser.uid)
.get();
setState (() {
name = vari.data()['firstname'];
});
}
if you've saved your user's details in firestore and its document id is the same as that of user ID (which is preferred for ease of access and control), then:
var vari =FirebaseFirestore.instance.collection("users").doc(user!.uid).get();
This gets the document of the user, and the type is DocumentSnapshot.
Map<String,dynamic> userData = vari as Map<String,dynamic>;
now userData is stored in form of Map. suppose you want to access their 'name', so the syntax now goes like userData['name'].
Similarly other fields can be accessed from variable. It's preferred to store userData in a Provider to access it's contents anywhere in your app.
Full code snippet
void getData() async{
User? user = await FirebaseAuth.instance.currentUser;
var vari =FirebaseFirestore.instance.collection("users").doc(user!.uid).get();
Map<String,dynamic> userData = vari as Map<String,dynamic>;
setState (() {
name = userData['firstname']; //or name = userData['name']
}
);
}

Flutter, How to use multiple shared preferences

My goal was to avoid users getting logged out once they close and reopened the app. So, I used shared_preferences to store the user's email and password locally so, that whenever the user reopens the app I could use firebase's signInWithEmailAndPassword and provide locally stored email and password to it. I used setString() to store email password but I was able to store only email and not the password, I get the error "Password is null" How do I solve this. Did I do the code right?
Storing email and password when user registers in app
onPressed: () async {
try {
final user =
await _auth.createUserWithEmailAndPassword(
email: email, password: password);
if (user != null) {
final SharedPreferences sharedPreferences =
await SharedPreferences.getInstance();
sharedPreferences.setString(
'email',
email,
);
sharedPreferences.setString('password', password);
Get.to(() => const BorrowerList());
}
} catch (e) {
Get.snackbar('Error', e.toString(),
backgroundColor: (Colors.red));
}
},
fetching email password and login after reopening.
#override
void initState() {
super.initState();
validateUserAuth();
}
final _firestore = FirebaseFirestore.instance;
void validateUserAuth() async {
final SharedPreferences sharedPreferences =
await SharedPreferences.getInstance();
var obtainedEmail = sharedPreferences.getString('email');
var obtainedPassword = sharedPreferences.getString('password');
if (obtainedEmail != null || obtainedPassword != null) {
setState(() {
loggedinUserEmail = obtainedEmail!;
loggedinUserPassword = obtainedPassword!;
});
if (loggedinUserEmail != null || loggedinUserPassword != null) {
final loggedinuser = await auth.signInWithEmailAndPassword(
email: loggedinUserEmail, password: obtainedPassword!);
if (loggedinuser != null) {
Get.to(() => const BorrowerList());
}
}
} else {
Get.to(() => AuthScreen());
}
}
The error is apparent.
You can't save a null value in shared_preferences.
Your code is not complete. somehow your password variable is null.
You can paste complete code so we can help you better
Can you provide more information about the project? So far, it's obvious that you're trying to store a null value in shared_preferences. You can't do that. I'm pretty sure the problem is that when the user enters a password, it's not stored in the password variable here:
try {
final user =
await _auth.createUserWithEmailAndPassword(
email: email, password: password);
if (user != null) {
final SharedPreferences sharedPreferences =
await SharedPreferences.getInstance();
sharedPreferences.setString(
'email',
email,
);
// NULLABLE VARIABLE!
sharedPreferences.setString('password', password);
Get.to(() => const BorrowerList());
}
} catch (e) {
Get.snackbar('Error', e.toString(),
backgroundColor: (Colors.red));
}
},
Additionally, it is not recommended to use shared_preferences for storing sensitive data. Flutter Secure Storage is much better suited for this.

how to fix: handleWindowVisibility: no activity for token android.os.BinderProxy bug

I am using flutter_facebook_auth to login and register my user. Backend - firebase.
class FacebookSignInProvider extends ChangeNotifier {
Map<String, dynamic> _userData;
Future<UserCredential> signInWithFacebook(BuildContext context) async {
final LoginResult result = await FacebookAuth.i.login(
permissions: ['name', 'email', 'user_birthday', 'user_gender'],
);
if(result.status == LoginStatus.success){
final userData = await FacebookAuth.i.getUserData(fields: "username,
email, birthday, gender");
_userData = userData;
final OAuthCredential credential =
FacebookAuthProvider.credential(result.accessToken.token);
return await FirebaseAuth.instance.signInWithCredential(credential);
}
Navigator.of(context).pushReplacement(
CupertinoPageRoute(builder: (_) => TabScreen()));
notifyListeners();
return null;
}
}
This goes to the FB Sorry, something went wrong screen.
What bug is this?

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});
}