Flutter Firebase Collection Sorting...认为我只有一步之遥

Flutter Firebase Collection Sorting... Think I'm Only A Step Away

更新 所以行 'final CollectionReference golfCartCollection = FirebaseFirestore.instance.collection('golf_cart');'工作并传递数据但是,如果我将 'CollectionReference' 更改为 'Query',它会在代码中进一步分解 '// 将新产品保存到 Firestore // await golfCartCollection.add({' with .add error要求提取方法和“//更新产品//等待golfCartCollection.doc(documentSnapshot!.id)”,并出现 .doc 错误要求提取方法。 结束更新

好的。我正在“自学”扑朔迷离,已经走到这一步了。按照教程、示例等,我现在可以通过 ListViews 显示信息,但是使用示例并将它们组合起来存在问题。我无法对 ListView 进行排序。

如果我将“CollectionReference”更改为“查询”,正如许多人指出的那样,我将失去功能并进一步出错。

请检查代码,如果可能的话,请将我推向正确的道路。一如既往,我感谢您提供的所有帮助。

顺便说一句,这是在 iOS 和 Android 模拟器上使用 VSCode 的 Flutter with Firebase。我将附上 ListView 屏幕的屏幕截图。

  const GolfCartdbScreen({Key? key}) : super(key: key);
  @override
  _GolfCartdbScreenState createState() => _GolfCartdbScreenState();
}

class _GolfCartdbScreenState extends State<GolfCartdbScreen> {
  static final DateTime now = DateTime.now();
// // YES there are many text controllers. Its a registration for golf carts and need this info. Will add the remaining controllers when I get it working // //
  final _date = TextEditingController(text: '$now');
  late bool _active;
  final addCityController = TextEditingController(text: 'Welaka');
  final addStateController = TextEditingController(text: 'FL');
  final TextEditingController addStreetController = new TextEditingController();
  final addZipController = TextEditingController(text: '32193');
  final TextEditingController businessNameController =
      new TextEditingController();
  final TextEditingController dateInitialController =
      new TextEditingController();
  final TextEditingController dateRenewController = new TextEditingController();
  final TextEditingController emailController = new TextEditingController();
  final TextEditingController firstNameController = new TextEditingController();
  final TextEditingController lastNameController = new TextEditingController();
  final TextEditingController phoneNumberController =
      new TextEditingController();
  final TextEditingController regNumberController = new TextEditingController();
  final TextEditingController timeStampController = new TextEditingController();
  final TextEditingController vehColorController = new TextEditingController();
  final TextEditingController vehMakeController = new TextEditingController();
  final TextEditingController vehModelController = new TextEditingController();
  final TextEditingController vinNumberController = new 
// // // THE TWO LINES BELOW WORK TO PROVIDE THE DATA HOWEVER IF I CHANGE TO QUERY HAVE ISSUE FURTHER DOWN WITH 'await golfCartCollection.add' AND ' await golfCartCollection.doc(documentSnapshot!.id)' WITH ADD and DOC HAVING ERRORS // // //
  final CollectionReference golfCartCollection =
      FirebaseFirestore.instance.collection('golf_cart');

// This function is triggered when the floating button or one of the edit buttons is pressed
// Adding a product if no documentSnapshot is passed
// If documentSnapshot != null then update an existing product

  Future<void> _createOrUpdate([DocumentSnapshot? documentSnapshot]) async {
    String action = 'create';
    if (documentSnapshot != null) {
      action = 'update';
      addStreetController.text = documentSnapshot['addStreet'].toString();
      firstNameController.text = documentSnapshot['firstName'].toString();
      lastNameController.text = documentSnapshot['lastName'].toString();
    }
    await showModalBottomSheet(
        isScrollControlled: true,
        context: context,

        builder: (BuildContext ctx) {
          return Padding(
            padding: EdgeInsets.only(
                top: 20,
                left: 20,
                right: 20,
                bottom: MediaQuery.of(ctx).viewInsets.bottom + 20),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                TextField(
                  controller: firstNameController,
                  decoration: const InputDecoration(labelText: 'Fisrt Name'),
                ),
                TextField(
                  controller: lastNameController,
                  decoration: const InputDecoration(
                    labelText: 'Last Name',
                  ),
                ),
                TextField(
                  controller: addStreetController,
                  decoration: const InputDecoration(
                    labelText: 'Address: Street',
                  ),
                ),
                const SizedBox(
                  height: 20,
                ),
                ElevatedButton(
                  style: ElevatedButton.styleFrom(
                    primary: CustomColors.welakaoneBlack,
                  ),
                  child: Text(action == 'create' ? 'Create' : 'Update'),
                  onPressed: () async {
                    final String? firstName = firstNameController.text;
                    final String? lastName = lastNameController.text;
                    final String? addStreet = addStreetController.text;
                    if (firstName != null &&
                        lastName != null &&
                        addStreet != null) {
                      if (action == 'create') {
// Persist a new product to Firestore
                        await golfCartCollection.add({
                          "firstName": firstName,
                          "lastName": lastName,
                          "addStreet": addStreet
                        });
                      }
                      if (action == 'update') {
// Update the product
                        await golfCartCollection
                            .doc(documentSnapshot!.id)
                            .update({
                          "firstName": firstName,
                          "lastName": lastName,
                          "addStreet": addStreet
                        });
                      }
// Clear the text fields
                      firstNameController.text = '';
                      lastNameController.text = '';
                      addStreetController.text = '';
// Hide the bottom sheet
                      Navigator.of(context).pop();
                    }
                  },
                )
              ],
            ),
          );
        });
  }

// Deleteing a product by id
  Future<void> _deleteProduct(String productId) async {
    await golfCartCollection.doc(productId).delete();
// Show a snackbar
    ScaffoldMessenger.of(context).showSnackBar(
      const SnackBar(
        content: Text('You Have Successfully Deleted The Registration.'),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        systemOverlayStyle: SystemUiOverlayStyle.dark,
        backgroundColor: CustomColors.welakaoneBlack,
        title: AppBarTitle(),
        leading: Builder(
          builder: (context) {
            return IconButton(
              onPressed: () {
                Scaffold.of(context).openDrawer();
              },
              icon: Icon(Icons.menu),
            );
          },
        ),
        actions: <Widget>[
          Builder(
            builder: (context) {
              return IconButton(
                onPressed: () {
                  Scaffold.of(context).openEndDrawer();
                },
                icon: Icon(Icons.person),
              );
            },
          ),
        ],
      ),
      drawer: new MyDrawer(),
      endDrawer: new MyEndDrawer(
        uid: '',
      ),
// Using StreamBuilder to display all products from Firestore in real-time
      body: new Container(
        height: MediaQuery.of(context).size.height,
        width: MediaQuery.of(context).size.width,
        decoration: const BoxDecoration(
          gradient: LinearGradient(
            colors: [
              CustomColors.welakaoneBlack,
              CustomColors.welakaoneBlueDark,
            ],
            begin: FractionalOffset(0.0, 0.0),
            end: FractionalOffset(1.6, 1.0),
            stops: [0.3, 1.0],
            tileMode: TileMode.clamp,
          ),
        ),
        child: StreamBuilder(
          stream: golfCartCollection.snapshots(),
          builder: (context, AsyncSnapshot<QuerySnapshot> streamSnapshot) {
            if (streamSnapshot.hasData) {
              return ListView.builder(
                itemCount: streamSnapshot.data!.docs.length,
                itemBuilder: (context, index) {
                  final DocumentSnapshot documentSnapshot =
                      streamSnapshot.data!.docs[index];
                  return Card(
                    color: Colors.transparent,
                    margin: const EdgeInsets.all(0),
                    child: ListTile(
                      title: Text(
                        documentSnapshot['firstName'].toString() +
                            ' ' +
                            documentSnapshot['lastName'.toString()],
                        style: TextStyle(
                          fontSize: 18,
                          fontWeight: FontWeight.bold,
                          color: CustomColors.welakaoneWhite,
                        ),
                      ),
                      subtitle: Text(
                        documentSnapshot['addStreet'].toString(),
                        style: TextStyle(
                          fontSize: 16,
                          fontWeight: FontWeight.normal,
                          color: CustomColors.welakaoneWhite,
                        ),
                      ),
                      trailing: SizedBox(
                        width: 100,
                        child: Row(
                          children: [
// Press this button to edit a single product
                            IconButton(
                                icon: const Icon(Icons.edit),
                                color: CustomColors.welakaoneYellow,
                                onPressed: () =>
                                    _createOrUpdate(documentSnapshot)),
// This icon button is used to delete a single product
                            IconButton(
                                icon: const Icon(Icons.delete),
                                color: CustomColors.welakaoneYellow,
                                onPressed: () =>
                                    _deleteProduct(documentSnapshot.id)),
                          ],
                        ),
                      ),
                    ),
                  );
                },
              );
            }
            return const Center(
              child: CircularProgressIndicator(
                valueColor: AlwaysStoppedAnimation<Color>(
                  CustomColors.welakaoneYellow,
                ),
              ),
            );
          },
        ),
      ),
// Add new product
      floatingActionButton: FloatingActionButton(
        backgroundColor: CustomColors.welakaoneYellow,
        onPressed: () => _createOrUpdate(),
        child: const Icon(
          Icons.add,
          color: CustomColors.welakaoneBlueDark,
        ),
      ),
    );
  }
}
[![enter image description here][1]][1] ```


  [1]: https://i.stack.imgur.com/5STK5.jpg

要对列表视图进行排序,请在此处添加一个 order-by 子句:

...
child: StreamBuilder(
  stream: golfCartCollection.orderBy('lastName').snapshots(),
  ...