I'm trying to retrieve data from Firebase. Here's my code snippet
Future main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
// DatabaseReference ref = FirebaseDatabase.instance.ref();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
final docRef = FirebaseFirestore.instance.collection('data').doc("rules");
docRef.get().then(
(DocumentSnapshot doc) {
final data = doc.data() as Map<String, dynamic>;
return MyHomePage(title: 'ARNET Helper',
rules: data['ruleslist']);
},
one rror: (e) => print("Error getting document: $e"),
);
return Spinner(text: "Unable to retrieve data");
}
}
Here's the corresponding Firebase database screenshot
I do have the google-services.json added to the android/app folder. But with the above snippet, lines from the "then" block don't seem to get hit and the spinner (i.e return Spinner(text: "Unable to retrieve data");) is always returned.
I do have these lines added to AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET"/>
I tried to debug it. But the breakpoint at line 46 is never hit. Instead the execution goes straight to line 52. What am I missing?
CodePudding user response:
Did you initialize the Firebase Instance?
await Firebase.initializeApp()
CodePudding user response:
The problem is that get()
is an asynchronous operation, and you can't return widgets asynchronously in build
.
The simplest way to fix this is to use a FutureBuilder
:
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
return FutureBuilder<String>(
future: FirebaseFirestore.instance.collection('data').doc("rules").get(),
builder: (BuildContext context, AsyncSnapshot<DocumentSnapshot> asyncSnapshot) {
if (snapshot.hasData) {
final data = asyncSnapshot.data!.data() as Map<String, dynamic>;
return MyHomePage(title: 'ARNET Helper', rules: data['ruleslist']);
}
else if (snapshot.hasError) {
return Text("Error: ${snapshot.error}")
}
else {
return Text("Loading user data...")
}
}
)
}