簡體   English   中英

Flutter - Firestore - 列出來自集合字段的字符串,並在按下“保存設置”后更新 Fire Store

[英]Flutter - Firestore - List String to be from collection field and update fire store once "Save Setting' is pressed

我有兩個問題:

1.我需要使用 email 作為選擇標准從文檔中構建一個列表字符串,所以我的查詢是

  Future<List<dynamic>> getDevices() async {
    var firebaseUser = FirebaseAuth.instance.currentUser?.email;
    var query = await firestoreInstance
        .collection(devices)
        .where('email', isEqualTo: '$firebaseUser')
        .get();

    //This is to get the Document ID to a List String, but I actually want this List String to be a
    // List String of the deviceName
    List<String> _documentsIds = query.docs.map((doc) => doc.id).toList();
    return _documentsIds;
  }

我如何 map 將設備名稱添加到列表中? 目前我 map doc.id

2.為了構建 NumberPicker,我使用 startHour 來指示開始時間。 但是每次你 select 使用 NumberPicker 一個新的“開始時間”時,它都會導致調用未來並查詢 Firesote,你無法更新該值。 假設要等到我按“保存設置”然后更新 Firestore。 關於如何實現這一目標的任何建議?

在此處輸入圖像描述

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
import 'package:safe/constants.dart';
import 'package:safe/components/buttons_navigate.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:numberpicker/numberpicker.dart';

class Test2 extends StatefulWidget {
  const Test2({Key? key}) : super(key: key);
  static const String id = 'test_2';

  @override
  State<Test2> createState() => _Test2State();
}

class _Test2State extends State<Test2> {
  final _auth = FirebaseAuth.instance;
  User? loggedInUser;

  final firestoreInstance = FirebaseFirestore.instance;
  final String devices = 'devices';

  bool showSpinner = false;

  String? deviceName;
  int startHour = 0;
  String? selectedDeviceValue;
  final bool checkOne = false;
  Color sDeviceAlways = Colors.white54;
  Color sDeviceTime = Colors.white54;
  FontWeight sDeviceAlwaysW = FontWeight.normal;
  FontWeight sDeviceTimeW = FontWeight.normal;

  @override
  void initState() {
    super.initState();
    getCurrentUser();
  }

  void getCurrentUser() async {
    try {
      final user = await _auth.currentUser;
      if (user != null) {}
      ;
    } catch (e) {
      print(e);
    }
  }

  Future<List<dynamic>> getDevices() async {
    var firebaseUser = FirebaseAuth.instance.currentUser?.email;
    var query = await firestoreInstance
        .collection(devices)
        .where('email', isEqualTo: '$firebaseUser')
        .get();

    //This is to get the Document ID to a List String, but I actually want this List String to be a
    // List String of the deviceName
    List<String> _documentsIds = query.docs.map((doc) => doc.id).toList();
    return _documentsIds;
  }

  Future<DocumentSnapshot<Map<String, dynamic>>> getDeviceSettings() async {
    var deviceSetting = await firestoreInstance
        .collection(devices)
        .doc(selectedDeviceValue)
        .get();

    startHour = deviceSetting.data()!['startHour'];
    deviceName = deviceSetting.data()!['deviceName'];

    print(deviceSetting.data());
    print('deviceName: $deviceName');
    print('startHour: $startHour');

    return deviceSetting;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          leading: null,
          actions: [
            IconButton(
                onPressed: () {
                  _auth.signOut();
                  Navigator.pop(context);
                },
                icon: Icon(Icons.close))
          ],
          title: const Text('Device Selection page'),
        ),
        body: ModalProgressHUD(
          inAsyncCall: showSpinner,
          child: Container(
              child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              const SizedBox(
                height: 40,
                child: Text(
                  'SAFE',
                ),
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Container(
                    width: 380,
                    padding: const EdgeInsets.symmetric(horizontal: 24.0),
                    decoration: BoxDecoration(
                        border: Border.all(
                            color: Colors.lightBlueAccent, width: 1.0),
                        borderRadius: kBorderRadius),
                    child: DropdownButtonHideUnderline(
                        child: FutureBuilder<List>(
                            future: getDevices(),
                            builder: (BuildContext context,
                                AsyncSnapshot<List<dynamic>> snapshot) {
                              if (!snapshot.hasData) {
                                return const Text(
                                  'Waiting Devices',
                                );
                              } else {
                                return DropdownButton(
                                  borderRadius: kBorderRadius,
                                  iconSize: 40,
                                  elevation: 16,
                                  hint: const Text(
                                    'Safe Devices',
                                  ),
                                  onChanged: (value) {
                                    setState(() {
                                      selectedDeviceValue = value.toString();
                                      setState(() {
                                        selectedDeviceValue;
                                        getDeviceSettings();
                                      });
                                    });
                                  },
                                  value: selectedDeviceValue,
                                  items: snapshot.data
                                      ?.map((_documentsIds) =>
                                          DropdownMenuItem<String>(
                                            value: _documentsIds,
                                            child: Text(_documentsIds),
                                          ))
                                      .toList(),
                                );
                              }
                            })),
                  )
                ],
              ),
              SizedBox(
                height: 5,
              ),
              // This Future is to update startHour according to selectedDeviceValue selected
              // The problem is every time you change the NumberPicker it recalls from Firesore the value of
              // startHour, it is suppose to update the startHour and only store it in Firestore once you
              // press 'Save Settings'
              FutureBuilder(
                  future: getDeviceSettings(),
                  builder: (BuildContext context,
                      AsyncSnapshot<DocumentSnapshot<Map<String, dynamic>>>
                          snapshot) {
                    if (!snapshot.hasData) {
                      return const Text(
                        'Please select a Devices',
                      );
                    } else {
                      return Column(
                        children: [
                          Row(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: [
                              Column(
                                children: [
                                  Container(
                                    width: 180,
                                    decoration: BoxDecoration(
                                        border: Border.all(
                                            color: Colors.lightBlueAccent,
                                            width: 1.0),
                                        borderRadius: kBorderRadius),
                                    child: Column(
                                      crossAxisAlignment:
                                          CrossAxisAlignment.center,
                                      children: [
                                        Container(
                                          padding: const EdgeInsets.fromLTRB(
                                              5, 10, 5, 1),
                                          child: const Text(
                                            'Start Time',
                                          ),
                                        ),
                                        Container(
                                          padding: const EdgeInsets.fromLTRB(
                                              1, 1, 25, 1),
                                          child: NumberPicker(
                                            value: startHour,
                                            minValue: 0,
                                            maxValue: 24,
                                            onChanged: (value) => setState(
                                                () => startHour = value),
                                          ),
                                        )
                                      ],
                                    ),
                                  )
                                ],
                              )
                            ],
                          ),
                        ],
                      );
                    }
                  }),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Buttons_Navigate(
                    colour: Colors.teal,
                    title: 'Save Settings',
                    onPressed: () {},
                    width: 200,
                  ),
                ],
              ),
            ],
          )),
        ));
  }
}

對於第一個問題,我認為您可以使用List<String> devicesNames = query.docs.map((doc['deviceName']) => deviceName).toList();

讓我知道這個是否奏效

對於第二個問題,我真的沒有得到你想要什么,你能解釋一下嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM