This is the code:
// ignore_for_file: prefer_const_constructors, prefer_const_literals_to_create_immutables
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:google_nav_bar/google_nav_bar.dart';
import 'package:projectciplified/screens/read%20data/get_user_name.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
#override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final user = FirebaseAuth.instance.currentUser!;
//document ids
List<String> docIDs = [];
// method to get document ids
Future getDocID() async {
await FirebaseFirestore.instance.collection('users').get().then(
(snapshot) => snapshot.docs.forEach(
(document) {
print(document.reference);
docIDs.add(document.reference.id);
},
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
user.email!,
style: TextStyle(fontSize: 16),
),
actions: [
GestureDetector(
onTap: () {
FirebaseAuth.instance.signOut();
},
child: Icon(Icons.logout)),
],
),
bottomNavigationBar: Container(
color: Colors.black,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 15,
vertical: 20.0,
),
child: GNav(
backgroundColor: Colors.black,
color: Colors.white,
activeColor: Colors.white,
tabBackgroundColor: Colors.blue,
padding: EdgeInsets.all(10),
gap: 2,
onTabChange: (index) {},
tabs: [
GButton(
icon: Icons.home,
text: 'Home',
),
GButton(
icon: Icons.favorite_border,
text: 'likes',
),
GButton(
icon: Icons.search,
text: 'search',
),
GButton(
icon: Icons.settings,
text: 'settings',
),
],
),
),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: FutureBuilder(
future: getDocID(),
builder: (context, snapshot) {
return ListView.builder(
itemCount: docIDs.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: ListTile(
tileColor: Colors.grey[200],
title: GetUserName(documentID: docIDs[index]),
),
);
},
);
},
)),
],
),
),
);
}
}
I'm trying to get the user info with FirebaseAuth.instance.currentUser! but it's giving said error.
With FirebaseAuth.instance.currentUser (without the !) The code works but why?
Can someone explain the null error? I'm not sure why this code doesn't work as it worked around 5 hours ago. How do I fix it? Thanks for your help.
There are few states FutureBuilder provides, like connection state, error state and data or empty state. While you calling future it needs some time to fetch data, means first state is loading state and data is not ready yet. That's why it says null error because we don't have any data.
Do like
FutureBuilder(
future: getDocID(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: Text('Please wait its loading...'));
} else if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error}'));
} else if (snapshot.hasData) {
return ListView(...);
}
else return Text("dont have any data")
},
Find more about FutureBuilder on flutter.dev.
Related
I want to show current user data in my flutter app. But it print on screen " No data found".
This my database data
That error also happened error
My security rule
enter image description here
Here is my code
Container(
child: StreamBuilder(
stream: FirebaseFirestore.instance.collection("user3").where("id",isEqualTo:FirebaseAuth.instance.currentUser!.uid).snapshots(),
builder: (BuildContext context,AsyncSnapshot<QuerySnapshot> snapshot){
if(!snapshot.hasData){
return Text("Loading please wait........");
}
if (snapshot.hasData && snapshot.data!.docs.length > 0) {
DocumentSnapshot userData = snapshot.data!.docs[0];
// Build the widget using the userData
} else {
return Center(child: Text("No data found"));
}
return Container();
},
),
),
The long numeric values (e.g. "167582...") in your database screenshot do not look like a UID that any of the Firebase Authentication providers would generate.
Add this code right before you query the database:
print(FirebaseAuth.instance.currentUser!.uid)
This will show you the value that you're querying for, which (given my opening statement) probably looks quite different from the value in your database.
If that is indeed the case, the problem starts when you write the document. At that point you'll want to make sure that you write the value of FirebaseAuth.instance.currentUser!.uid to the id field.
I am trying to build an app with Flutter and Dart. Here, I want to retrieve data from my Firebase, and I was able to do so and put it in the replies variable in each Message object that I have as an array type in the Firebase by using a for loop. However, when I try to access the replies variable again, it becomes empty.
I tried using setState, but that just causes the replies variable to keep resetting. Why this is the case, and how can I fix it?
StreamBuilder<List<Message>> pickMessage(
Stream<List<Message>> list, BuildContext context) {
return StreamBuilder(
stream: list,
builder: (context, snapshot) {
if (snapshot.hasError) {
return const Text('Something went wrong!');
} else if (snapshot.hasData) {
final message = snapshot.data!;
for (var msg in message) {
FirebaseFirestore.instance.collection("messages").doc(msg.msgID).get().then((value){
msg.replies = value.get("replies");
});
}
If You Need Some Variable to Initialize Once Put in Init Function or In Builder Function, outside the Scope of StreamBuilder, hope it helps
I want a user to give a value in my app and other user to see it. But i can upload data to firebase but not get it on the other side. I have null safety enabled on flutter. The code is :-
child: StreamBuilder(
stream:FirebaseFirestore.instance.collection('Collection name').doc('doc id').snapshots()
builder: (context, snapshot){
if(snapshot.hasData){
return Text(snapshot.data['Field name'].toString()); // here my editor shows error saying 'The method '[]' can't be unconditionally invoked because the receiver can be 'null'.' and asks for a null check and then shows error again
}
return Text('Nothing');
}
),
Edit: I am getting only 'type '_JsonDocumentSnapshot' is not a subtype of type 'Map<String, dynamic>' in type cast' as the error
And if I change
if(snapshot.hasData){
return Text(snapshot.data['Field name'].toString());
to
if (snapshot.hasData) {
return Text(snapshot.data.toString());
}
i get output as
'Instance of '_JsonDocumentSnapshot''
where the data should be.
I am using null check dart
Thannks for everyone's support, but i have accidently found and answer. I read that the data type of that is DocumentSnapshot and this worked for me
builder: (context, snapshot) {
if (snapshot.hasData) {
var numGuess = snapshot.data as DocumentSnapshot;
return Text(numGuess['Field name'].toString());
}
return Text('Nothing');
}
This works for null safety.
Since you are retrieving a collection then try the following:
return Text(snapshot.data!.docs[0].data()["Field Name"]);
A collection will return a list of documents, therefore use the docs property to be able to access the document. The above code will show the field in the first document in the list, it's better if you use a listview to return all documents.
Check:
https://api.flutter.dev/flutter/widgets/ListView-class.html
Give datatype to your StreamBuilder like this
StreamBuilder<DocumentSnapshot<Map<String, dynamic>>>(
stream:
FirebaseFirestore.instance.collection('Collection name').doc('doc id').snapshots(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data?.data()?['Field name']);
}
return Text('Nothing');
},
),
I have tried calling a list and a simple future in a single program and I also searched for this in the web I didn't get a solution
studentDetails.dart
Future<List<Stud>> studentDetails(http.Client client, var lin) async {
print(lin);
//Codes
return studList;
}
fetchhistory.dart
Future<AttendanceHistory> fetchhistory(http.Client client, String id) async {
//codes
return parsedJson;
}
I want these service file to be called in one component file.
studentView.dart
// Scaffold codes
body: FutureBuilder(
future: Future.wait([
studentDetails(http.Client(), widget.sid),
fetchhistory(http.Client(), widget.sid),
]),
builder: (context,AsyncSnapshot<List<dynamic>> snapshot) {
if (snapshot.hasError) print(snapshot.error);
return snapshot.hasData
// lab: widget.label
? StudListView(
stud: snapshot.data[0],
his:snapshot.data[1]
)
: Center(child: CircularProgressIndicator());
},
),
//scaffold codes
Error Screenshot
I have the only problem in the implementation that how can I use 2 service calls inside the Body of the Scaffold Please help me because I am seriously tended to solve this error.
Thank you
I'm currently working on an app and I want to get some data of a user's friends. Ideally, after sign in, this information is loaded up onto the screen for viewing.
I initially made my function call to do this within the "build" method of my HomeScreen, but this caused an infinite loop as the function call ended with "notifyListeners()".
That being said, where should I place my call to avoid a loop, while still having the UI update once the data has been fetched from the database?
You should have a look at the FutureBuilder widget, which provides great functionality to load async data and show the result once available. While the data is loading, or if your code runs into an error, you can show a different widget. Essentially it works like this:
FutureBuilder<String>(
future: _yourFuture,
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.active:
case ConnectionState.waiting:
// Return loading indicator
return Container();
case ConnectionState.done:
if (snapshot.hasError) {
// Return error
return Container();
} else if (snapshot.hasData) {
// Data loaded => use snapshot.data to access it
return Container();
}
}
})
I would not recommend to load data during initState(), since this method cannot be async and thus, you cannot await your result.
I hope that helps.