Hi friends,
I want to load data from my Firebase Cloud Firestore database and paginate all data, I tried all the samples and examples but I'm stuck for more than a week, please guide me with this, thanks!
My OrderInfoDataGridSource script:
But all the time I'm getting null data from Firebase :( and I don't know why, any help will be much appreciated!
The main widget:
Please help or guide me with this issue, thanks in advance!
Hi Dorin Buraca,
Based on the information provided, we thoroughly tested the application using
the same Firebase Firestore backend structure, which includes a stream
(collection) -> companies (document) -> all (collection) hierarchy.
Our tests on our end showed no issues, and data retrieval from Firestore was
successful.
Could you please provide details about the print methods that are executed within the `buildStream` method and the output values they produce? Additionally, kindly confirm whether `snapshot.hasData` returns false, leading to the display of an 'Error or empty' text on the screen. If you observe this behavior, please double-check that the collection and document names are correctly matched.
Furthermore, we've examined your code and are unclear about how you construct rows based on the underlying collection orders and the steps you follow in the `_buildDataGrid` method.
To assist you more effectively, we kindly request that you share the entire sample (excluding Firebase credentials) so that we can conduct debugging on our end. By providing the sample, you will greatly assist us in identifying and resolving the issue.
As a reference, we've attached a simple sample (excluding
Firebase credentials) that we tested on our end. Please review the attached
sample and the Firestore structure outlined in the provided image.
Regards,
Tamilarasan
Attachment: Sample_de3f9e66.zip
Hi @Tamilarasan,
I managed to make it work from your example, thanks a lot, I changed the code:
I'm loading the data from Firebase without problems now.
What I want to achieve and I'm not able is to paginate the data to load first for example 25 per page, after that maybe on Infinite scroll to load the next 25...25...25, and so on. I tried to combine this with your great examples, but I'm not able to, please help me or guide me, because I will have thousands of items on the list and this feature is mandatory for me.
Thanks in advance!
Dorin Buraca,
Based on the information provided, we are not completely clear about your
specific requirements. Could you please clarify whether you are looking to
implement paging where 25 rows are loaded on each page and the next 25 rows are
loaded when you switch to another page, or if your intention is to achieve
continuous loading of additional rows through infinite scrolling? To provide
you with the most accurate guidance and assistance, we would greatly appreciate
more detailed information about your requirements.
Hi Tamilarasan,
I apologize for the confusion, I tried both ways with pagination and with infinite scrolling, but I think that for me the best option at this moment would be infinite scrolling.
I have tried in many ways but I am also confused and totally blocked at this moment on how I do this with live data from Firebase, please help me.
Have a great day and thanks again!
Kind regards,
Hi Dorin Buraca,
To implement infinite scrolling and load data from Firestore in response to scrolling, you can utilize the `handleLoadMoreRows` method. Within this method, you can fetch an additional set of 25 rows, map the details as `DataGridRow` instances, add them to the local DataGridRows collection, and subsequently invoke `notifyListeners` to refresh the DataGrid. We've prepared a sample that demonstrates this approach. Please refer to the provided sample and code snippet for a more detailed understanding.
|
In EmployeeDataSource class:
class EmployeeDataSource extends DataGridSource { EmployeeDataSource(this.employeeData) { if (employeeData.isNotEmpty) { _buildDataRow(); } }
final collection = FirebaseFirestore.instance .collection('stream') .doc('companies') .collection('all');
Stream<QuerySnapshot> getStream() { return collection .limit(10) .orderBy('companyID', descending: false) .snapshots(); }
List<DataGridRow> dataGridRows = []; List<Employee> employeeData;
void _buildDataRow() { dataGridRows = employeeData .map<DataGridRow>((e) => DataGridRow(cells: [ DataGridCell<String>(columnName: 'id', value: e.id), DataGridCell<String>( columnName: 'companyName', value: e.companyName), DataGridCell<String>(columnName: 'city', value: e.city), DataGridCell<String>(columnName: 'country', value: e.country), ])) .toList(); }
@override Future<void> handleLoadMoreRows() async { await Future.delayed(const Duration(seconds: 5));
// Here we are getting the last dataGridRow's companyID // It's unique ID and we are using it to get the last documet // from the FireStore collection. var lastRowCompanyID = dataGridRows.last.getCells()[0].value;
// Here we are getting the last document from the FireStore collection var lastDoument = await collection .where("companyID", isEqualTo: lastRowCompanyID) .get() .then((value) => value.docs.first);
// Here we are getting the next 10 documents from the FireStore collection // by using the last document from the previous query. var snap = await collection.startAfterDocument(lastDoument).limit(10).get();
// Here we are mapping the data to the DataGridRow // and adding it to the dataGridRows list. // The dataGridRows is the local collection // which is assigned to the `rows` property of DataGridSource. for (var data in snap.docs) { dataGridRows.add(DataGridRow(cells: [ DataGridCell<String>(columnName: 'id', value: data['companyID']), DataGridCell<String>( columnName: 'companyName', value: data['companyName']), DataGridCell<String>(columnName: 'city', value: data['city']), DataGridCell<String>(columnName: 'country', value: data['country']), ])); }
notifyListeners(); }
@override List<DataGridRow> get rows => dataGridRows; … }
In Main Class:
Widget _buildDataGrid() { return StreamBuilder( stream: employeeDataSource.getStream(), builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) { if (snapshot.hasData) { for (var data in snapshot.data!.docs) { employeeData.add(Employee( id: data['companyID'], companyName: data['companyName'], city: data['city'], country: data['country'])); } employeeDataSource = EmployeeDataSource(employeeData);
return SfDataGrid( source: employeeDataSource, columns: getColumns, columnWidthMode: ColumnWidthMode.fill, loadMoreViewBuilder: (BuildContext context, LoadMoreRows loadMoreRows) { Future<String> loadRows() async { await loadMoreRows(); return Future<String>.value('Completed'); }
return FutureBuilder<String>( initialData: 'loading', future: loadRows(), builder: (context, snapShot) { if (snapShot.data == 'loading') { return Container( height: 60.0, width: double.infinity, decoration: const BoxDecoration( color: Colors.white, border: BorderDirectional( top: BorderSide( width: 1.0, color: Color.fromRGBO(0, 0, 0, 0.26)))), alignment: Alignment.center, child: const CircularProgressIndicator()); } else { return SizedBox.fromSize(size: Size.zero); } }, ); }, ); } else { return const Center( child: CircularProgressIndicator(), ); } }, ); } |
We hope that this helps you. If you require further clarification or additional assistance, please let us know. We are happy to help you out.
Regards,
Tamilarasan