I have been working with google sign in and I need to display the email but I can not get set state working can someone pls help!
Here is my current code:
const Padding(
padding: EdgeInsets.fromLTRB(9, 0, 9, 0),
child: SignInButton(),
),
Text(userEmail ?? 'email') // i need the email to update when i sign in
],
),
);
}
}
final _auth = FirebaseAuth.instance;
dynamic? user;
String? userEmail;
String? userPhoneNumber;
void getCurrentUserInfo() async {
user = await _auth.currentUser!;
userEmail = user.email;
userPhoneNumber = user.phoneNumber;
}
void getCurrentUserInfo() async {
user = await _auth.currentUser!;
userEmail = user.email;
userPhoneNumber = user.phoneNumber;
setState((){})
}
assuming you are in a stateful widget. Just add setState() in getCurrentUserInfo and it should update the widget.
Related
I want to be logged in as an admin but also wanna create user login credentials for other users. using createUserWithEmailAndPassword() method but it accidentally logging a newly created user.
enter image description hereI have tried the other methods but not working in my case. Please helps me with this.
SAMPLE CODE::
class _TestScreenState extends State<TestScreen> {
final _emailController = TextEditingController();
final _passwordController = TextEditingController();
final FirebaseFirestore _fs = FirebaseFirestore.instance;
final FirebaseAuth _auth = FirebaseAuth.instance;
bool _isLoading = false;
final User _currentUser = FirebaseAuth.instance.currentUser;
Future<void> _createUser() async {
try {
setState(() {
_isLoading = true;
});
await _auth
.createUserWithEmailAndPassword(
email: _emailController.text,
password: _passwordController.text,
)
.then((UserCredential _user) async {
try {
await _fs.collection('users').doc(_user.user.uid).set({
'email': _emailController.text,
'password': _passwordController.text,
}).then((value) {
setState(() {
_isLoading = false;
});
});
} catch (err) {
_user.user.delete();
print("User Deleted");
setState(() {
_isLoading = false;
});
}
});
} catch (err) {
print("Cannot Sign Up: $err");
setState(() {
_isLoading = false;
});
}
}
#override
Widget build(BuildContext context) {
print("USER--" + _currentUser.uid);
return Scaffold(
appBar: AppBar(title: Text("Test Screen")),
body: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
TextField(
controller: _emailController,
),
SizedBox(
height: 20,
),
TextField(
controller: _passwordController,
),
SizedBox(height: 30),
ElevatedButton(
onPressed: _createUser,
child: Text(_isLoading ? "Creating..." : "Create User"),
),
],
),
),
);
}
}
In Firebase Authentication there is a single signed-in user for each FirebaseAuth object. If you want to sign in multiple users, you will need multiple instances of the FirebaseAuth class, based on an explicit FirebaseApp object (instead of the default FirebaseAuth.instance).
Note that this is a common anti-pattern though. For example, wanting to have a administrative user in the app who can create other user accounts, is typically better handled by creating a custom back-end API (for example on Cloud Functions), where you can then the Admin SDK that is specifically made for such administrative functionality.
hey guys i trying to login with google using firebase in flutter but its always return null in the next page
how can i get the current user in the next page after login with google
i already connect with firebase and generate sha-1 and sha-256
here's the code
login button
onPressed: () async {
setState(() {
_isSigningIn = true;
});
try {
final user = await googleSignIn.signIn();
final googleAuth = await user.authentication;
final credential = GoogleAuthProvider.credential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken
);
final googleAccount = await FirebaseAuth.instance.signInWithCredential(credential);
if(googleAccount != null) {
Navigator.pushReplacementNamed(context, HomeScreen.id);
}
} catch (e) {
final snackbar = SnackBar(content: Text(e.toString()));
_scaffoldKey.currentState.showSnackBar(snackbar);
} finally {
setState(() {
_isSigningIn = false;
});
}
},
home_screen.dart
class _HomeScreenState extends State<HomeScreen> {
final _auth = FirebaseAuth.instance;
User _currentUser;
void getCurrentUser() async {
try {
var currentUser = await _auth.currentUser;
if (currentUser != null) {
_currentUser = currentUser;
}
} catch(e) {
print(e);
}
}
#override
void initState() {
super.initState();
getCurrentUser();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(_currentUser.email),
),
);
}
}
thank you
This line is an asynchronous function, it is for this reason that you receive null, you must add an await.
final googleAccount = await FirebaseAuth.instance.signInWithCredential(credential);
In addition to this, to access the information of the current user you must do it this way.
googleAccount.user
Upon creating an account the user's firestore creates a field that displays the current amount of plastics the user has. So far, I have a button that updates that amount using the user's text field input. I've heard of something called a transaction which apparently allows one to intsead add the input amount to the overall data for it to be displayed? How would I accomplish this in my case when the use inputs a new amount?
Code:
database.dart
Future<void> userSetup(String displayName) async {
int plastics = 0;
final CollectionReference users =
FirebaseFirestore.instance.collection('UserNames');
FirebaseAuth auth = FirebaseAuth.instance;
String uid = auth.currentUser.uid.toString();
users.doc(uid).set({'displayName': displayName, 'uid': uid});
//This is the field for plastics amount starting at 0.
users.doc(uid).update({'plastics': plastics});
return;
}
How I retrieve the amount data:
final firestore = FirebaseFirestore.instance;
FirebaseAuth auth = FirebaseAuth.instance;
Future<String> getPlasticNum() async {
final CollectionReference users = firestore.collection('UserNames');
final String uid = auth.currentUser.uid;
final result = await users.doc(uid).get();
return result.data()['plastics'].toString();
}
How I display it:
FutureBuilder(
future: getPlasticNum(),
builder: (_, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
}
return Text(snapshot.data,
style: TextStyle(color: Colors.amber[400], fontSize: 20));
},
),
Currently how the user can replace the amount, but not add to it(The problem)
OnPressed: () async {
try {
final String uid = auth.currentUser.uid;
FirebaseFirestore.instance
.collection('UserNames')
.doc(uid)
.update({
"plastics": int.parse(_plasticController.text),
});
Navigator.of(context).pop();
} catch (e) {}
},
I made a separate future to take care of adding:
final firestore = FirebaseFirestore.instance; //
FirebaseAuth auth = FirebaseAuth.instance;
Future<bool> addPlastic(String amount) async {
try {
String uid = auth.currentUser.uid;
var value = double.parse(amount);
DocumentReference documentReference =
FirebaseFirestore.instance.collection('UserNames').doc(uid);
FirebaseFirestore.instance.runTransaction((transaction) async {
DocumentSnapshot snapshot = await transaction.get(documentReference);
if (!snapshot.exists) {
documentReference.set({'plastics': value});
return true;
}
double newAmount = snapshot.data()['plastics'] + value;
transaction.update(documentReference, {'plastics': newAmount});
return true;
});
} catch (e) {
return false;
}
}
Then I just called it when the button was pressed
onPressed(){
addPlastics(_plasticController.text);
}
I am trying to get the email of the user to display it in the account page, This is what I did :
getuseremail() async {
FirebaseAuth _auth = FirebaseAuth.instance;
String email;
final user = _auth.currentUser();
setState() {() {
email = user.email;
}}
}
and Then I display it but It gives me error that it is null.
You can try this code :
String _email;
void getUserEmail() {
FirebaseAuth.instance.currentUser().then((user) {
setState(() {
_email = user.email;
});
});
}
1, currentUser is return Future
2, _email is need define a field on State to setState
If the user is currently logged in then you have to do the following:
getuseremail() async {
FirebaseAuth _auth = FirebaseAuth.instance;
String email;
final user = await _auth.currentUser();
setState() {() {
email = user.email;
}}
}
Use await since currentUser() returns a Future<FirebaseUser>, but make sure the user is currently logged in or you won't be able to get the email.
Can you try this?
final user = _auth.currentUser;
or use:
final user = _auth.getCurrentUser();
How can I set a user's displyName at the same time as creating their account?
I'm using the createUserWithEmailAndPassword method and trying to take the information from 3 different TextFormFields within the same Form.
Below is a very simple example of what I'm trying to do... Hopefully from this someone will be able to help..
Thanks
This is my signup method:
import 'package:firebase_auth/firebase_auth.dart';
class AuthService {
FirebaseAuth auth = FirebaseAuth.instance;
//Create user with email and password (+ displayName)
signUp({String email, String password, String name}) async {
await FirebaseAuth.instance
.createUserWithEmailAndPassword(email: email, password: password);
// I'd like to create/update the new user's displayName here, using the String value (name) being passed into this function.
}
}
This is an example of where the data is coming from:
class SignUpForm extends StatelessWidget {
final GlobalKey<FormState> _formKey = GlobalKey();
String name;
String email;
String password;
TextEditingController nameController;
TextEditingController emailController;
TextEditingController passwordController;
submit(){
AuthService().signUp(password: 'password', email: email, name: name);
}
#override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Column(
children: <Widget>[
TextFormField(
controller: nameController,
onChanged: (value) {
name = value;
},
),
TextFormField(
controller: emailController,
onChanged: (value) {
email = value;
},
),
TextFormField(
controller: passwordController,
onChanged: (value) {
password = value;
},
),
],
),
);
}
}
The user object is returned from the createUserWithEmailAndPassword function's promise and you can then update the displayName immediately after by issuing a further request to firebase.
await FirebaseAuth.instance.createUserWithEmailAndPassword(email: email, password: password)
.then((user){
var userUpdateInfo = new UserUpdateInfo(); //create user update object
userUpdateInfo.displayName = "John Doe"
await firebaseAuth.updateProfile(userUpdateInfo); //update to firebase
await user.reload(); //reload user data
})
More info about UserUpdateInfo class here:
https://pub.dev/documentation/firebase_auth/latest/firebase_auth/UserUpdateInfo-class.html
You may also want to check out the example app on the firebase github repository. I've linked to the file and line which is relevant to what you are seeking to achieve:
https://github.com/FirebaseExtended/flutterfire/blob/7ccdd3b9bca948d15b397fe5c86ec4616b611c47/packages/firebase_auth/firebase_auth/example/lib/register_page.dart#L88
EDIT
Final working code:
class AuthService {
FirebaseAuth auth = FirebaseAuth.instance;
signUp({String email, String password, String name}) async {
await FirebaseAuth.instance
.createUserWithEmailAndPassword(email: email, password: password)
.then(
(value) async {
var userUpdateInfo = new UserUpdateInfo(); //create user update object
userUpdateInfo.displayName = "John Doe";
await value.user.updateProfile(userUpdateInfo); //update to firebase
await value.user.reload();
print('displayname= ${userUpdateInfo.displayName}');
},
);
}
}
_createUser() async {
await _auth
.createUserWithEmailAndPassword(
email: emailText,
password: passwordText,
)
FirebaseUser user = await _auth.currentUser();
UserUpdateInfo updateInfo = UserUpdateInfo();
updateInfo.displayName = 'John Doe';
await user.updateProfile(updateInfo);
print('USERNAME IS: ${user.displayName}');
}