user3030327
user3030327

Reputation: 451

How to show firestore all document fields on PaginatedDataTable or datatable as streambuilder on flutter web?

I am able to show normal text fields on PaginatedDataTable. But I want to show my Firestore fields on PaginatedDataTable as stream builder method. I have searched on internet but I could not find relevant to my requirement. How to get firestore data in to PaginatedDataTable source. Or is there any other way Please let me know. Looking for solution and It is very useful if there is get on tapeable row or selectable row also. I want to fetch data from firestore only not from firebase auth. And I have named the firestore collection name as "users". it my be different also Need help how to do this? if it is not possible in PaginatedDataTable, DataTable also fine.

Below is my example Firestore collection and document structure:

firestore collection name: users

documentID1-
    email: 'email1'
    name : 'name1'
    role : 'role1'
    uid  : 'uid1'

documentID2-
    email: 'email2'
    name : 'name2'
    role : 'role2'
    uid  : 'uid2'   

(more than 20 documents)

Below is my example code which is normally able to show with normal text:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';

class AdminDashboard extends StatefulWidget {
  const AdminDashboard({Key? key}) : super(key: key);

  @override
  _AdminDashboardState createState() => _AdminDashboardState();
}

class _AdminDashboardState extends State<AdminDashboard> {
  final DataTableSource _allUsers = UsersData();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(16),
        child: PaginatedDataTable(
          header: const Text("Header Text"),
          rowsPerPage: 9,
          columns: const [
            DataColumn(label: Text('Uid')),
            DataColumn(label: Text('Name')),
            DataColumn(label: Text('Email')),
            DataColumn(label: Text('Role'))
          ],
          source: _allUsers,
        ),


      ),
    );
  }
}

class UsersData extends DataTableSource {
  //final List<Map<String, dynamic>> _allUsers = [{}];
  @override
  DataRow getRow(int index) {
    return DataRow.byIndex(
      index: index,
      cells: [
        DataCell(Text('row #$index')),
        DataCell(Text('name #$index')),
        DataCell(Text('name #$index')),
        DataCell(Text('name #$index')),
      ],
    );
  }

  @override
  bool get isRowCountApproximate => false;

  @override
  int get rowCount => 9;

  @override
  int get selectedRowCount => 0;
}

Please find below image of Errors after edited as per @xBurnsed Answer.

image

Upvotes: 6

Views: 804

Answers (1)

xBurnsed
xBurnsed

Reputation: 452

Haven't had the chance to test this but something like the following should point you to the right direction:

@override
Widget build(BuildContext context) {
  
    List<User> users;
    return StreamBuilder(
        padding: const EdgeInsets.all(16),
        stream: Firestore.instance.collection("[YOUR_COLLECTION_NAME").snapshots(),
        builder: (context, AsyncSnapshot<QuerySnapshot> snap) {
            users = snap.data.docs.map((e) => User.fromMap(e.data)).toList();
            final DataTableSource _allUsers = UsersData(users);
            if(snap.hasData){
                return PaginatedDataTable(
                  header: const Text("Header Text"),
                  rowsPerPage: 9,
                  columns: const [
                    DataColumn(label: Text('Uid')),
                    DataColumn(label: Text('Name')),
                    DataColumn(label: Text('Email')),
                    DataColumn(label: Text('Role'))
                  ],
                  source: _allUsers,
                );
            }
            else{
                return new Text('No data...');
            }
    });
}


class UsersData extends DataTableSource {
  final List<User> users;

  UsersData(this.users);
  
  DataRow getRow(int index) {
     return DataRow.byIndex(cells: [
      DataCell(Text(users[index].uid)),
      DataCell(Text(users[index].name)),
      DataCell(Text(users[index].email)),
      DataCell(Text(users[index].role)),
    ], index: index);
  }

  @override
  bool get isRowCountApproximate => false;

  @override
  int get rowCount => 9;

  @override
  int get selectedRowCount => 0;
}

You will have to create your User class for this to work tho so you are able to populate your source, if you don't want to, you can always use a List<DataRow> in your DataTableSource instead of a List<User> and manually map each cell.

Upvotes: 0

Related Questions