Thanks in advance!
Flutter & Firestore
I'm checking if the user is an admin. I have a collection 'users', within: a bool: admin: true or false. If it's true it shows the admin Screen. Else it shows the main screen.
The problem: the first 1 second I get this Screen. (see screen shot, only 1 second visible) Is there an option to use a loading indicator when the app gets the data from firestore.
I tried adding if (currentUser.admin == null) {}
But that doesn't work.
User currentUser;
//I made a separate modal document
#override
void initState() {
super.initState();
pageController = PageController(initialPage: 0);
getUser();
}
getUser() async {
final FirebaseUser user = await FirebaseAuth.instance.currentUser();
DocumentSnapshot doc =
await Firestore.instance.collection("users").document(user.uid).get();
setState(() {
currentUser = User.fromDocument(doc);
});
print(currentUser.admin);
}
#override
Widget build(BuildContext context) {
if (currentUser.admin == true) {
return AdminScreen(
currentUser: currentUser,
);
} else {
return mainScreen();
}
}
}
Screenshot
UPDATE: tried this:
getUser() async {
final FirebaseUser user = await FirebaseAuth.instance.currentUser();
DocumentSnapshot doc =
await Firestore.instance.collection("users").document(user.uid).get();
if (doc.exists) {
try {
setState(() {
currentUser = User.fromDocument(doc);
});
} catch (e) {
print(e);
}
}
Found it!
For anyone having the same issue.
This was the problem:
if (currentUser.admin == true)
It should be: if (currentUser == null) or if (currentUser != null)
it doesn't work with currentUser.xxxx
You can also do as follows
Firestore.instance
.collection('driverListedRides')
.getDocuments()
.then((QuerySnapshot snapshot) => {
snapshot.documents.forEach((f) {
String _variableName = f.data["YourCollectionFieldId"];
})
});
Related
i'm trying to upload picture and register user information into firebase storage and firestore the problem is it's not accepting this code for some reason it says i need to put ; after _registerUser()
here is the code i'm using to save and upload information :
Future<void> uploadAndSaveImage() async {
if (_imageFile != null) {
_passwordTextEditingController.text ==
_cPasswordTextEditingController.text
? _emailTextEditingController.text.isNotEmpty &&
_passwordTextEditingController.text.isNotEmpty &&
_cPasswordTextEditingController.text.isNotEmpty &&
_nameTextEditingController.text.isNotEmpty
?uploadToStorage() , _registerUser()
: displayDialog("Please fill up the registration complete form..")
: displayDialog("Password do not match.");
} else {
showDialog(
context: context,
builder: ((c) {
return ErrorAlertDialog(
message: "Please select an image.",
);
}));
}
}
the regiser user function :
FirebaseAuth _auth = FirebaseAuth.instance;
void _registerUser() async {
FirebaseUser firebaseUser;
await _auth
.createUserWithEmailAndPassword(
email: _emailTextEditingController.text.trim(),
password: _passwordTextEditingController.text.trim(),
)
.then((auth) {
firebaseUser = auth.user;
}).catchError((error) {
Navigator.pop(context);
showDialog(
context: context,
builder: (c) {
return ErrorAlertDialog(
message: error.message.toString(),
);
});
});
if (firebaseUser != null) {
saveUserInfoToFireStore(firebaseUser).then((value) {
Navigator.pop(context);
Route route = MaterialPageRoute(builder: (c) => StoreHome());
Navigator.pushReplacement(context, route);
});
}
}
Ps: i'm still new to this it's my third app with flutter
I have used this code to upload the user image from local storage to Firebase with uid as the reference name.
final _firebaseAuth = FirebaseAuth.instance;
FirebaseStorage firebaseStorage = FirebaseStorage.instance;
FirebaseFirestore firebaseFirestore = FirebaseFirestore.instance;
final imgPicker = ImagePicker();
File image;
String photoUrl = "";
bool _uploading = false;
uploadPic() async {
try {
setState(() {
_uploading = true;
});
// picking Image from local storage
final file = await imgPicker.getImage(
source: ImageSource.gallery,
);
if (file != null) {
image = File(file.path);
} else {
setState(() {
_uploading = false;
});
}
// creating ref at Firebase Storage with userID
Reference ref =
firebaseStorage.ref(_firebaseAuth.currentUser.uid).child("dp");
ref.putFile(image).whenComplete(() {
print("Pic Uploaded Successfully!");
setState(() {
_uploading = false;
});
// refreshing the UI when photo updated
getUploadedPic();
});
} catch (e) {
print(e);
}
}
After uploading you may get the image URL as follow:
getUploadedPic() async {
// getting dp URL link
photoUrl = await firebaseStorage
.ref("${_firebaseAuth.currentUser.uid}/dp")
.getDownloadURL()
.whenComplete(() => print("URL UPLOADED AT: $photoUrl"));
}
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
I have a flutter app and I am trying to fetch favorites data from cloud firestore database depending on userId.
The problem is that data are returned back without the right favorite items status true or false.
when I print favoriteData in console, I receive empty map like this: {}
Here is my code and how I tried to achieve this:
Future<void> fetchProducts() async {
final List<Product> loadedProducts = [];
var userId = await getCurrentUser();
final response = await Firestore
.instance
.collection("products")
.getDocuments();
final favoriteResponse = await Firestore.instance
.collection("userFavorites")
.document(userId)
.collection("MyFavorites")
.getDocuments();
final favoriteData = favoriteResponse.documents.asMap();
try{
print(favoriteData.toString());
response.documents.forEach((element) {
loadedProducts.add(Product(
id: element.documentID,
title: element.data['title'],
price: element.data['price'],
isFavorite: favoriteData == null ? false : favoriteData[element.documentID] ?? false,
));
});
_items = loadedProducts;
notifyListeners();
}catch(error){
print(error);
}
}
Here where I call fetchProducts which includes favourited items:
class _ProductsScreenState extends State<ProductsScreen> {
var _showOnlyFavorites = false;
var _isInit = true;
var _isLoading =false;
#override
void initState() {
super.initState();
}
#override
void didChangeDependencies() {
if(_isInit){
setState(() {
_isLoading = true;
});
Provider.of<Products>(context,listen: false).fetchProducts().then((_) {
setState(() {
_isLoading = false;
});
});
}
_isInit = false;
super.didChangeDependencies();
}
Here is a screenshot of documents I am trying to get their value:
Trying to capture a specific field from my documents. Here is the code for the wrapper,
class Wrapper extends StatelessWidget {
#override
Widget build(BuildContext context) {
final user = Provider.of<User>(context);
print(user);
// return either the Home or Authenticate widget
if (user == null) {
return Authenticate();
} else {
return FirmHomePage();
}
}
}
and this is the code that we used for printing in the console.
void idss() async {
FirebaseUser userid = await FirebaseAuth.instance.currentUser();
var document = await Firestore.instance.collection('Users').getDocuments();
for (var document in document.documents) {
messagetext = document.data['JobType'];
usettype = messagetext;
print(messagetext);
}
}
We want to check our user to set a path for them.
FirebaseUser userid = await FirebaseAuth.instance.currentUser();
final QuerySnapshot result = await Firestore.instance.collection('Users')
.where('uid', isEqualTo: currentUser.uid) .getDocuments();
final List < DocumentSnapshot > documents = result.documents;
if (documents.length == 1) {
//your code here
}else{
//your code here
}
I know this question has been asked a lot and I have spent a lot of time reading and trying to implement the answers. So I am trying to get the response from isEmailVerified from Firebase Auth to work and it does work but right now it always returns false unless I refresh the app or close it and reopen it. which is obviously a bad user experience. How do I get the response to update without having to close the app.
here is the relevant pieces of code.
Future<bool> isEmailVerified() async {
FirebaseUser user = await _auth.currentUser();
if (user == null) {
return false;
} else {
await user.reload();
user = await _auth.currentUser();
return user.isEmailVerified;
}
}
main.dart
child: Consumer<Auth>(
builder: (_, auth, __) => MaterialApp(
theme: Provider.of<ThemeNotifier>(context).getTheme(),
home: FutureBuilder(
future: Future.wait([auth.isEmailVerified(), auth.tryAutoLogin()]),
builder: (BuildContext ctx, AsyncSnapshot authResultSnapshot) =>
authResultSnapshot.connectionState == ConnectionState.done
? authResultSnapshot.data[1]
? authResultSnapshot.data[0]
? HearingsScreen()
: SplashScreen(
emailVerified: true,
)
: LoginScreen()
: SplashScreen(),
),
It is not returning true until I restart the app
Things I have tried besides this:
1) await user.getIdToken(refresh: true);
2) sign user out then back in
3) firebase_user_stream package
Any help is appreciated.
I have implemented the same scenario in a splash screen with below code, you can change it as per your requirement. :
//To check is User is logged in
Future<bool> isLoggedIn() async {
FirebaseUser user = await _fireBaseAuth.currentUser();
if (user == null) {
return false;
}
return user.isEmailVerified;
}
and
countDownTime() async {
return Timer(
Duration(seconds: splashDuration),
() async {
if (await userAuth.isLoggedIn()) {
Navigator.pushReplacement(
context,
ScaleRoute(
widget: HomeScreen(),),
);
}
} else {
Navigator.pushReplacement(
context,
ScaleRoute(
widget: LoginScreen(),),
);
}
},
);
}
and
#override
void initState() {
super.initState();
countDownTime();
}
Update
One needs to implement isEmailVerified in initState() function periodically which can be the ideal approach to execute the verification with firebase.
bool _isUserEmailVerified;
Timer _timer;
#override
void initState() {
super.initState();
// ... any code here ...
Future(() async {
_timer = Timer.periodic(Duration(seconds: 10), (timer) async {
await FirebaseAuth.instance.currentUser()..reload();
var user = await FirebaseAuth.instance.currentUser();
if (user.isEmailVerified) {
setState((){
_isUserEmailVerified = user.isEmailVerified;
});
timer.cancel();
}
});
});
}
#override
void dispose() {
super.dispose();
if (_timer != null) {
_timer.cancel();
}
}