Reputation: 11
I am Trying to read the data from the firebase realtime Database in my Flutter app and assign it to model class but, i am getting the following error in console.
E/flutter ( 9052): [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: NoSuchMethodError: Class 'List<dynamic>' has no instance getter 'keys'.
E/flutter ( 9052): Receiver: _List len:3
E/flutter ( 9052): Tried calling: keys
E/flutter ( 9052): #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:54:5)
E/flutter ( 9052): #1 _MyHomePageState.initState.<anonymous closure> (package:app/main.dart:64:27)
E/flutter ( 9052): #2 _rootRunUnary (dart:async/zone.dart:1362:47)
E/flutter ( 9052): #3 _CustomZone.runUnary (dart:async/zone.dart:1265:19)
E/flutter ( 9052): #4 _FutureListener.handleValue (dart:async/future_impl.dart:152:18)
E/flutter ( 9052): #5 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:704:45)
E/flutter ( 9052): #6 Future._propagateToListeners (dart:async/future_impl.dart:733:32)
E/flutter ( 9052): #7 Future._completeWithValue (dart:async/future_impl.dart:539:5)
E/flutter ( 9052): #8 _completeOnAsyncReturn (dart:async-patch/async_patch.dart:254:13)
E/flutter ( 9052): #9 Query.once (package:firebase_database/src/query.dart)
E/flutter ( 9052): <asynchronous suspension>
Following is the Code I have Done So far
Employee Class
class Employee {
final String id;
final String name;
final String email;
final String emp_id;
const Employee({this.id,this.name,this.email,this.emp_id});
}
import 'dart:convert';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:shimmer/shimmer.dart';
import 'Employee.dart';
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List <Employee> myAllData = [];
@override
void initState() {
super.initState();
DatabaseReference ref = FirebaseDatabase.instance.reference();
ref.child('employee').once().then((DataSnapshot snap){
var keys = snap.value.keys;
var data = snap.value;
for (var key in keys){
Employee d = new Employee(
id : data [key]['id'],
name : data[key]['name'],
email : data[key]['email'],
emp_id: data[key]['emp_id']
);
myAllData.add(d);
}
setState(() {
print('Length : ${myAllData.length}');
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
);
}
}
I am unable to figure out what i am doing wrong, please help me to resolve the issue
Upvotes: 0
Views: 1473
Reputation: 31
I had same problem.
Basically here we are trying to access all the document IDs from DB and using that ID we Store all the data in List using our UserModel.
The Problem is we are not able to access those Document IDs.
To Solve the issue
Change the initState() method like this.
@override
void initState() {
super.initState();
final ref = FirebaseDatabase.instance.ref().child('employee');
ref.once().then((snap){
//TO retrieve all the documents from collection
dynamic keys = snap.snapshot.value;
//To get only the document IDs of all documents.
dynamic KEYS = keys.keys;
dynamic data = snap.snapshot.value;
for (var key in KEYS){
Employee d = new Employee(
id : data [key]['id'],
name : data[key]['name'],
email : data[key]['email'],
emp_id: data[key]['emp_id']
);
myAllData.add(d);
}
setState(() {
print('Length : ${myAllData.length}');
});
});
Thank You!
Upvotes: 1
Reputation: 598817
The error seems pretty clear. You're calling var keys = snap.value.keys;
and there is no keys
on the snap.value
. From this, it seems that you think snap.value
is a Map
object, which doesn't seem to be the case.
From looking at your data structure, it is more likely that snap.value
is actually a List
object.
This is because Firebase interprets objects with sequential, numeric keys are arrays. If this is indeed the case (something you can easily verify by running the code in a debugger), you can iterate over the list with:
for (var child in snap.value){
Also see:
Upvotes: 0