FetchData From Cloud FireStore Firebase in flutter (dart) - firebase

This is my Fire Base cloud store structure the data is stored in the document is as Map<string,Dynamic>
What Would be the Query if i want to fetch the username to corresponding uid ?
Also , i want return the username to a text widget
Language Used : Dart
String getUserName (User user) {
String username;
/* Query */
return username;
}
class username extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Text("USER NAME : " + getUserName());
}
}
Please Help!

You can use the FlutterFire Package to read Data from your Firestore
https://firebase.flutter.dev/docs/firestore/usage/#one-time-read
Take a look at their example, you only have to make a few Adjustments:
class GetUserName extends StatelessWidget {
final String documentId; // This is your User UID
GetUserName(this.documentId);
#override
Widget build(BuildContext context) {
CollectionReference users = FirebaseFirestore.instance.collection('users');
return FutureBuilder<DocumentSnapshot>(
future: users.doc(documentId).get(),
builder:
(BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
if (snapshot.hasError) {
return Text("Something went wrong");
}
if (snapshot.connectionState == ConnectionState.done) {
Map<String, dynamic> data = snapshot.data.data();
return Text("USER NAME: ${data['name']}");
}
return Text("loading");
},
);
}
}

Related

logged in User Flutter return null ( data from Firebase )

I made Flutter project, and I want to show the name of logged in user, but the code (the yellow highlight)(https://i.stack.imgur.com/E2mU1.jpg) return null, the result be like "Name: + null" please help
I want to show the name of logged in user from the firebase
Use FutureBuilder,
Example -
class GetUserName extends StatelessWidget {
final String documentId;
GetUserName(this.documentId);
#override
Widget build(BuildContext context) {
CollectionReference users = FirebaseFirestore.instance.collection('users');
return FutureBuilder<DocumentSnapshot>(
future: users.doc(documentId).get(),
builder:
(BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
if (snapshot.hasError) {
return Text("Something went wrong");
}
if (snapshot.hasData && !snapshot.data!.exists) {
return Text("Document does not exist");
}
if (snapshot.connectionState == ConnectionState.done) {
Map<String, dynamic> data = snapshot.data!.data() as Map<String, dynamic>;
return Text("Full Name: ${data['full_name']} ${data['last_name']}");
}
return Text("loading");
},
);
}
}
https://firebase.flutter.dev/docs/firestore/usage

Flutter Androit | Firebase Authentication Persistance with Firestore

I wan't to persist authentication state of an user registered in Firebase Auth. The user has data in Firestore DB.
My final attempt :
main.dart
#override
Widget build(BuildContext context) {
return StreamProvider<AppUser?>.value(
value: AuthenticationService().user,
initialData: null,
child: const ....
);
}
home.dart
#override
Widget build(BuildContext context) {
var user = Provider.of<AppUser?>(context);
print(user);
Home.user = user;
...
}
authentication.dart
class AuthenticationService {
final FirebaseAuth _auth = FirebaseAuth.instance;
final FirebaseFirestore _db = FirebaseFirestore.instance;
final CollectionReference _usersCollection = FirebaseFirestore.instance.collection('users');
Stream<AppUser?> get user {
return _auth.authStateChanges().map((firebaseUser) {
AppUser? user;
_usersCollection.doc(firebaseUser!.uid).get().then((DocumentSnapshot userSnapshot) {
user = _toAppUser(firebaseUser, userSnapshot);
});
return user;
});
}
}
But with this code, the get user is always null, even just afte logging in
So after dozens of changes, the following code is "working" :
main.dart
#override
Widget build(BuildContext context) {
cart.cache();
return const MaterialApp(
title: 'CharleMi\'App',
debugShowCheckedModeBanner: false,
home: Home(),
);
}
home.dart
#override
Widget build(BuildContext context) {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (snapshot.hasData) {
AuthenticationService.delegate(snapshot.data).then((user) {
if (user != null) {
Home.user = user;
}
});
} else if (snapshot.hasError) {
print(snapshot.error);
}
return ....
authentication.dart
static Future<AppUser?> delegate(User? data) async {
return AuthenticationService()._toAsyncAppUser(data, null);
}
Future<AppUser?> _toAsyncAppUser(User? user) async {
AppUser _user = AppUser(uid: user!.uid);
var exists = await _user.init(); //Return true, get vars from firestore
if (exists) {
return _user; //Returned here when logging in (because exists)
}
return null;
}

Flutter firestore check if document with specific id exists

I want to check if the firestore document with a specific id exists. Actually, my idea is to store and fetch user-specific data from firestore. If there is no user-specific data uploaded it will show "no data to show" in the app. Till now what I have done is adding data to firestore with document id equals to the current user's UID.
FirebaseFirestore.instance.collection("doc_folder").doc(currentuser!.uid).set(data);
now I am unable to check if the firestore database contains any document with this data. By far, I have reached:
class Crud {
getData() {
return FirebaseFirestore.instance
.collection('doc_folder')
.where("userId", isEqualTo: currentUser!.uid)
.get();
}
}
#override
void initState() {
crud.getData().then((result) {
snap = result;
setState(() {});
});
super.initState();
}
Widget build(BuildContext context){
return Container(
snap != null? //if code
: //else code
)
}
The above code returns "document exists" even if the data does not exist with the current user's UID.
The following line from your code returns a QuerySnapshot which is not nullable:
FirebaseFirestore.instance.collection('doc_folder').where("userId", isEqualTo: currentUser!.uid).get()
and you assign the returned value of QuerySnapshot to snap and perform the following:
snap != null ? ... : ...
However, this condition will be true regardless of whether a document exists.
You should instead check docs property from QuerySnapshot, which is a list of the document snapshots returned for your query.
I'd prefer the widget of FutureBuilder over calling getData() in initState for this example to make it clear:
#override
Widget build(BuildContext context) {
return FutureBuilder<QuerySnapshot>(
future: crud.getData(),
builder: (context, snapshot) {
if (snapshot.hasData) {
if (snapshot.data.docs.isNotEmpty) {
// Document exists
} else {
// Document does not exist
}
} else {
// Show a loading widget
// ...
}
},
);
}
Full Example
class Crud {
Future<QuerySnapshot> getData() async {
return await FirebaseFirestore.instance
.collection('doc_folder')
.where("userId", isEqualTo: currentUser!.uid)
.get();
}
}
class MyPage extends StatefulWidget {
#override
_MyPageState createState() => _MyPageState();
}
class _MyPageState extends State<MyPage> {
final crud = Crud();
#override
Widget build(BuildContext context) {
return FutureBuilder<QuerySnapshot>(
future: crud.getData(),
builder: (context, snapshot) {
if (snapshot.hasData) {
final querySnaphost = snapshot.data; // Get query snapshot
if (querySnaphost.docs.isNotEmpty) {
// Document exists
final documentSnapshot =
querySnaphost.docs.first; // Get document snapshot
return Text('${documentSnapshot.data()}'); // Get the data
} else {
// Document does not exist
return Text('Document does not exist.');
}
} else {
// Show a loading widget
return CircularProgressIndicator();
}
},
);
}
}
The reason is that value of snapshot is not null even though document doesn't exists. So use below code:-
QuerySnapshot snap=await FirebaseFirestore.instance.collection('doc_folder').where("UserId", isEqualTo: currentuser!.uid).get();
if(snap.docs.isNotEmpty)
DocumentSnapshot doc=snap.docs.first;
print(doc['username']);//like this you can access data
else{
print("Doc doesn't exits");
}
You can do that
var
doc=FirebaseFirestore.instance
.collection('doc_folder')
.where("userId", isEqualTo:
currentUser!.uid)
.get();
if(doc.exist){
print('exist');
}
There is a slight problem with your code. build() is called while async crud.getData() is still running. Therefore snap will be have its default value. If snap's default value is not null, then snap != null will be true and you might assume your snap has its intended value.
Full working code
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Crud crud = Crud();
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Title'),
),
body: FutureBuilder<QuerySnapshot<Map<String, dynamic>>>(
future: crud.getData(),
// above is called everytime the widget is rebuilt which is not optimal
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot<Map<String, dynamic>>> snapshot) {
if (snapshot.hasError) return Text('Something went wrong');
if (snapshot.connectionState == ConnectionState.waiting)
return CircularProgressIndicator();
if (snapshot.data.docs.isNotEmpty) {
print('document exists');
print(snapshot.data.docs.map((e) => e.data()));
return Container();
} else {
print('document does not exist');
return Container();
}
},
),
);
}
}
class Crud {
Future<QuerySnapshot<Map<String, dynamic>>> getData() {
return FirebaseFirestore.instance
.collection('users')
.where("userId", isEqualTo: 'c1fG8zo0OWgHsPClEKWN')
.get();
}
}
FirebaseFirestore.instance
.collection('Company')
.doc('1235')
.get()
.then((value) {
if (value.exists) {
// Do something Here
}
The question asked to check if the document exists, and the answer accepted only works if docId is stored as field in that doc. Needs Review.

flutter Firestore data check and navigate to a new screen

I am trying to build a flutter app with Firestore .
I am trying to write a code wherein if a document if exists in Firestore in a collection then the user goes to a new screen if not he goes to an other screen
FirebaseAuth auth = FirebaseAuth.instance;
class check extends StatelessWidget {
static const String routeName = '/checkif';
#override
Widget build(BuildContext context) {
final firebaseUser = context.watch<User>();
final snapshot = fb.collection("Profile").doc(firebaseUser.uid).get();
if (snapshot == null) {
return addparentcompany();
} else{
return homepage();}
}
}
Even if the snapshot is null even then this gets routed to homepage instead of parent company
Because it takes time to fetch the data, You will have to wait for the data while its being retrieve.. So for that you'll have to use the FutureBuilder
body: FutureBuilder(
future: fb.collection("Profile").doc(firebaseUser.uid).get(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return addparentcompany();
} else {
if (snapshot.data.data() == null) {
return Center(
child: Text('An error occured'),
);
} else return homepage();
}
},
),

Flutter FirebaseAuth: How can i check if a User is LoggedIn in a void?

I am new in FirebaseAuth and i want, that in a void it check if the User is LoggedIn and if not, that he will be redirected.
That is my void:
void newEntry() {
showDialog<AlertDialog>(
context: context,
builder: (BuildContext context) {
return neuerEintrag(addItem);
});
}
And this is my check if the User os LoggedIn, in an other class:
class loginProfile extends StatelessWidget {
#override
Widget build(BuildContext context) {
final AuthService auth = Provider.of(context).auth;
return StreamBuilder<String>(
stream: auth.onAuthStateChanged,
builder: (context, AsyncSnapshot<String> snapshot) {
if (snapshot.connectionState == ConnectionState.active) {
final bool signedIn = snapshot.hasData;
return signedIn ? Profil() : FirstView();
}
return CircularProgressIndicator();
},
);
}
}
Thanks!
Maybe using the currentUser synchronous getter would be enough?
if (FirebaseAuth.instance.currentUser != null) {...}
ref: https://pub.dev/documentation/firebase_auth/latest/firebase_auth/FirebaseAuth/currentUser.html

Resources