【问题标题】:How to store and retrieve data to Firestore with the user unique id?如何使用用户唯一 ID 将数据存储和检索到 Firestore?
【发布时间】:2021-09-05 00:29:43
【问题描述】:

我正在尝试制作一个资金管理器应用程序,它有一个用户登录。当用户登录到应用程序时,他们将显示他们自己的交易。但我的问题是当用户登录时,用户可以看到所有数据(不仅是他们的数据),这意味着交易没有添加到唯一 ID,也不会根据登录系统的唯一 ID 显示。任何人都可以帮我解决这个问题吗?我找不到关于这个的任何资源。请帮我。谢谢

记录表

import 'package:dropdownfield/dropdownfield.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:monger_app/page/transaction_daily.dart';
import 'package:monger_app/theme/colors.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:intl/intl.dart';
import 'package:monger_app/page/record_code.dart';

class RecordExpense extends StatefulWidget {
  @override
  _RecordExpenseState createState() => _RecordExpenseState();
}

class _RecordExpenseState extends State<RecordExpense> {
  //DatabaseReference _ref;
  final date = TextEditingController();
  final category = TextEditingController();
  final amount = TextEditingController();
  final description = TextEditingController();
  final FirebaseAuth _auth = FirebaseAuth.instance;
  final databaseReference = FirebaseFirestore.instance;
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

  String _email, _password;

  Future<String> getCurrentUID() async {
    Future.value(FirebaseAuth.instance.currentUser);
    //return uid;
  }

  @override
  String selectExpense;

  final expenseSelected = TextEditingController();



  List <String> expensecategories = [
    "Food",
    "Social Life",
    "Transportation",
    "Beauty",
    "Household",
    "Education",
    "Health",
    "Gift",
    "Other"
  ];


  DateTime _selectedDate;

  void initState(){
    //_ref = FirebaseDatabase.instance.reference().child('Transaction');
  }

  Widget build(BuildContext context) {
    FirebaseFirestore firestore = FirebaseFirestore.instance;
    CollectionReference collect= firestore.collection("TransactionExpense");

    final FirebaseAuth _auth = FirebaseAuth.instance;
    final User user =_auth.currentUser;
    final uid = user.uid;


    String dates;
    String amounts;
    String selectExpenses;
    String descriptions;
    return new Form(
      child: SingleChildScrollView(
        child: Padding(
          padding: EdgeInsets.all(20.0),

          child: Column(
            key: _formKey,
            mainAxisAlignment: MainAxisAlignment.start,
            children: <Widget>[
              Container(
                child: TextField(
                  cursorColor: Colors.grey,
                  controller: date,
                  onTap: () {
                    _selectDate(context);
                  },
                  decoration: InputDecoration(
                    labelText: "Date",
                    labelStyle: TextStyle(
                        fontSize: 18.0, color: Colors.black),
                    hintText: "Select Date",
                    enabledBorder: UnderlineInputBorder(

                      borderSide: BorderSide(color: secondary),
                    ),
                    focusedBorder: UnderlineInputBorder(
                      borderSide: BorderSide(color: secondary),
                    ),
                  ),
                ),
              ),
              Container(
                //padding: EdgeInsets.all(20.0),
                child: TextField(
                  cursorColor: Colors.grey,
                  controller: amount,
                  decoration: InputDecoration(
                    labelText: "Amount",
                    labelStyle: TextStyle(
                        fontSize: 18.0, color: Colors.black),
                    hintText: "Amount",
                    enabledBorder: UnderlineInputBorder(

                      borderSide: BorderSide(color: secondary),
                    ),
                    focusedBorder: UnderlineInputBorder(
                      borderSide: BorderSide(color: secondary),
                    ),
                  ),
                  keyboardType: TextInputType.number,
                ),
              ),
              Container(
                padding: EdgeInsets.only(top: 20.0),
                child: Container(
                  decoration: BoxDecoration(
                    border: Border.all(color: secondary),
                    borderRadius: BorderRadius.circular(15.0),
                  ),
                  child: DropDownField(
                    controller: expenseSelected,
                    hintText: "Select Category",
                    labelText: "Category",
                    enabled: true,
                    itemsVisibleInDropdown: 4,
                    items: expensecategories,
                    onValueChanged: (dynamic value) {
                      selectExpense = value;
                    },
                    value: selectExpense,
                    required: false,
                  ),
                ),
              ),


              Container(
                //padding: EdgeInsets.all(20,0),
                child: TextField(
                  cursorColor: Colors.grey,
                  controller: description,
                  maxLines: 2,
                  decoration: InputDecoration(
                    labelText: "Descriptions",
                    labelStyle: TextStyle(
                        fontSize: 18.0, color: Colors.black),
                    hintText: "Expense Description",
                    enabledBorder: UnderlineInputBorder(

                      borderSide: BorderSide(color: secondary),
                    ),
                    focusedBorder: UnderlineInputBorder(
                      borderSide: BorderSide(color: secondary),
                    ),
                  ),
                ),
              ),
              Container(
                  padding: EdgeInsets.only(
                      top: 25.0, left: 20.0, right: 20.0),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      Expanded(
                        child: ElevatedButton(

                          onPressed: () async {
                            /*
                                UserCredential _user =
                                    await FirebaseAuth.instance.signInWithEmailAndPassword(email: _email, password: _password);
                                String _uid = _user.user.uid;

                                 */

                            //await FirebaseFirestore.instance.collection('TransactionExpense').doc(_uid).set({
                            /*
                                collect.add({
                                  'date': date.text,
                                  'amount': 'RM' + amount.text,
                                  'category': selectExpense,
                                  'description': description.text,
                              });
                              date.text = "";
                              amount.text = "";
                              description.text = "";

                                 */
                            final FirebaseAuth _auth = FirebaseAuth
                                .instance;
                            final User user = _auth.currentUser;
                            final uid = user.uid;

                            await DatabaseService().updateData(
                                uid, date.text, amount.text,
                                selectExpense, description.text);
                          },
                          child: Text(
                              "Save".toUpperCase(), style: TextStyle(
                            fontSize: 14,
                          )),
                          style: ButtonStyle(
                            padding: MaterialStateProperty.all<
                                EdgeInsets>(EdgeInsets.all(15)),
                            foregroundColor: MaterialStateProperty
                                .all<Color>(Colors.white),
                            backgroundColor: MaterialStateProperty
                                .all<Color>(Colors.pink),
                            shape: MaterialStateProperty.all<
                                RoundedRectangleBorder>(
                              RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(
                                      15.0),
                                  side: BorderSide(color: secondary)
                              ),
                            ),
                          ),

                        ),
                      ),
                      SizedBox(width: 20, height: 10),
                      Expanded(
                        child: ElevatedButton(
                          onPressed: () {
                            clearButton();
                          },
                          child: Text(
                              "Clear".toUpperCase(), style: TextStyle(
                              fontSize: 14
                          )),
                          style: ButtonStyle(
                            padding: MaterialStateProperty.all<
                                EdgeInsets>(EdgeInsets.all(15)),
                            foregroundColor: MaterialStateProperty
                                .all<Color>(Colors.white),
                            backgroundColor: MaterialStateProperty
                                .all<Color>(Colors.pink),
                            shape: MaterialStateProperty.all<
                                RoundedRectangleBorder>(
                              RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(
                                      15.0),
                                  side: BorderSide(color: secondary)
                              ),
                            ),
                          ),
                        ),
                      )
                    ],
                  )
              ),
            ],
          ),
        ),
      ),
    );
  }

  void clearButton(){
    date.clear();
    amount.clear();
    category.clear();
    description.clear();
  }
  _selectDate(BuildContext context) async {
    DateTime newSelectedDate = await showDatePicker(
        context: context,
        initialDate: _selectedDate != null ? _selectedDate : DateTime.now(),
        firstDate: DateTime(2000),
        lastDate: DateTime(2040),
        builder: (BuildContext context, Widget child) {
          return Theme(
            data: ThemeData.dark().copyWith(
              colorScheme: ColorScheme.dark(
                primary: secondary,
                onPrimary: Colors.black,
                surface: primary,
                onSurface: Colors.white,
              ),
              dialogBackgroundColor: Colors.black,
            ),
            child: child,
          );
        });

    if (newSelectedDate != null) {
      _selectedDate = newSelectedDate;
      date
        ..text = DateFormat.yMMMd().format(_selectedDate)
        ..selection = TextSelection.fromPosition(TextPosition(
            offset: date.text.length,
            affinity: TextAffinity.upstream));
    }
  }
}
class AlwaysDisabledFocusNode extends FocusNode {
  @override
  bool get hasFocus => false;
}

列表查看代码

    Widget build(BuildContext context) {
    FirebaseFirestore firestore = FirebaseFirestore.instance;
    CollectionReference collect = firestore.collection("TransactionExpense");

    final FirebaseAuth _auth = FirebaseAuth.instance;
    final User user = _auth.currentUser;
    final uid = user.uid;
    print('uid: $uid');

    String date = '';
    String amount = '';
    String selectExpense = '';
    String description = '';

    return FutureBuilder<DocumentSnapshot>(
        future: collect.doc(uid).get(),
        builder:
            (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
          if (snapshot.connectionState == ConnectionState.done) {
            Map<String, dynamic> data = snapshot.data.data();
            date = data['date'];
            amount = data['amount'];
            selectExpense = data['selectExpense'];
            description = data['description'];
            return ListView(children: [
              Center(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Row(
                      children: [
                        SizedBox(
                          width: 10,
                        ),
                        Text(
                          selectExpense,
                          style: TextStyle(
                              fontSize: 16,
                              color: primary,
                              fontWeight: FontWeight.w600),
                        ),
                      ],
                    ),
                    SizedBox(
                      height: 10,
                    ),
                    Row(
                      children: [
                        SizedBox(
                          width: 6,
                        ),
                        Text(
                          date,
                          style: TextStyle(
                              fontSize: 16,
                              color: primary,
                              fontWeight: FontWeight.w600),
                        ),
                        SizedBox(
                          width: 200,
                        ),
                        SizedBox(
                          width: 10,
                        ),
                        Text(
                          amount,
                          style: TextStyle(
                              fontSize: 16,
                              color: primary,
                              fontWeight: FontWeight.w600),
                        ),
                      ],
                    ),
                    SizedBox(
                      height: 8,
                    ),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.end,
                      children: [
                        GestureDetector(
                          onTap: () {
                            collect.doc(uid).delete();
                            //_showDeleteDialog();
                            //_showDeleteDialog(document: document);
                          },
                          child: Row(
                            children: [
                              Icon(
                                Icons.delete_forever_outlined,
                                color: Colors.red,
                              ),
                              SizedBox(
                                width: 6,
                              ),
                              Text(
                                'Delete',
                                style: TextStyle(
                                    fontSize: 16,
                                    color: Colors.red,
                                    fontWeight: FontWeight.w600),
                              ),
                            ],
                          ),
                        )
                      ],
                    )
                  ],
                ),
              )
            ]);
          } else {
            return Center(
              child: CircularProgressIndicator(),
            );
          }
        });
  }

【问题讨论】:

    标签: flutter google-cloud-firestore firebase-authentication


    【解决方案1】:
    /// This is how you can sign in
    UserCredential _userCredential = await FirebaseAuth.instance
        .signInWithEmailAndPassword(email: 'email', password: 'password');
    String uid = _userCredential.user.uid; // this is UID of logged in user
    
    /// Set data in document
    await FirebaseFirestore.instance.collection('your_collection').doc(uid).set({
      "key1": "Value1",
      "key2": "Value2",
    });
    
    /// Retrieve data from document
    await FirebaseFirestore.instance.collection('your_collection').doc(uid).get();
    
    /// Update data in document
    await FirebaseFirestore.instance.collection('your_collection').doc(uid).update({
      "key2": "updatedValue",
    });
    
    /// Delete document
    await FirebaseFirestore.instance.collection('your_collection').doc(uid).delete();
    

    【讨论】:

    • 您好,感谢您的回复。我应该为“您的唯一 ID”写什么?因为我试图让他们登录时,他们可以存储自己的数据(不与其他数据混合)
    • 登录后你会得到uid,这是你的唯一ID
    • 您使用哪种方式登录?注册时您不是将用户数据存储到 Firestore 吗?
    • 我正在使用 Firebase 身份验证,但我也将其存储到 firestore
    • 是的,但是所有的唯一 ID 都不一样,对吧?那么如果要获取登录系统的用户id应该怎么写呢?
    【解决方案2】:

    您可以通过以下方式从 firebase auth 获取唯一的用户 ID:

    final FirebaseAuth _auth = FirebaseAuth.instance;
    final User user =_auth.currentUser;
    final uid = user.uid;
    

    然后,当用户注册并阅读时,使用该 uid 在您的集合中创建一个唯一的文档:

    firestore.collection("TransactionExpense").doc(uid);
    

    创建一个新文件,随意命名。在该文件中:

    import 'package:cloud_firestore/cloud_firestore.dart';
    
    class DatabaseService {
      Future updateData(String uid, String date, String amount,
          String selectExpense, String description) async {
        CollectionReference collect =
            FirebaseFirestore.instance.collection("TransactionExpense");
        return await collect.doc(uid).set({
          'date': date,
          'amount': 'RM' + amount,
          'category': selectExpense,
          'description': description,
        });
      }
    }
    

    现在从您要更新的按钮:

    import 'YOUR_FILE_NAME';
    
    onPressed: () async {
    final FirebaseAuth _auth = FirebaseAuth.instance;
    final User user =_auth.currentUser;
    final uid = user.uid;
    
    await DatabaseService().updateData(uid, date.text, amount.text, selectExpense, description.text);
    
    }
    

    现在,在您的 firestore 数据库中,您应该为每个用户拥有不同的文档。

    要读取单个用户的数据,请在列表视图中使用FutureBuilder,如下所示:

    import 'package:flutter/material.dart';
    import 'package:cloud_firestore/cloud_firestore.dart';
    import 'package:firebase_auth/firebase_auth.dart';
    ...
    
    
    Widget build(BuildContext context) {
        FirebaseFirestore firestore = FirebaseFirestore.instance;
        CollectionReference collect = firestore.collection("TransactionExpense");
    
        final FirebaseAuth _auth = FirebaseAuth.instance;
        final User user = _auth.currentUser;
        final uid = user.uid;
        print('uid: $uid');
    
        String date = '';
        String amount = '';
        String selectExpense = '';
        String description = '';
    
        return FutureBuilder<DocumentSnapshot>(
            future: collect.doc(uid).get(),
            builder:
                (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
              if (snapshot.connectionState == ConnectionState.done) {
                Map<String, dynamic> data = snapshot.data.data();
                date = data['date'];
                amount = data['amount'];
                selectExpense = data['selectExpense'];
                description = data['description'];
                return ListView(children: [
                  Center(
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Row(
                          children: [
                            SizedBox(
                              width: 10,
                            ),
                            Text(
                              selectExpense,
                              style: TextStyle(
                                  fontSize: 16,
                                  color: primary,
                                  fontWeight: FontWeight.w600),
                            ),
                          ],
                        ),
                        SizedBox(
                          height: 10,
                        ),
                        Row(
                          children: [
                            SizedBox(
                              width: 6,
                            ),
                            Text(
                              date,
                              style: TextStyle(
                                  fontSize: 16,
                                  color: primary,
                                  fontWeight: FontWeight.w600),
                            ),
                            SizedBox(
                              width: 200,
                            ),
                            SizedBox(
                              width: 10,
                            ),
                            Text(
                              amount,
                              style: TextStyle(
                                  fontSize: 16,
                                  color: primary,
                                  fontWeight: FontWeight.w600),
                            ),
                          ],
                        ),
                        SizedBox(
                          height: 8,
                        ),
                        Row(
                          mainAxisAlignment: MainAxisAlignment.end,
                          children: [
                            GestureDetector(
                              onTap: () {
                                collect.doc(uid).delete();
                                //_showDeleteDialog();
                                //_showDeleteDialog(document: document);
                              },
                              child: Row(
                                children: [
                                  Icon(
                                    Icons.delete_forever_outlined,
                                    color: Colors.red,
                                  ),
                                  SizedBox(
                                    width: 6,
                                  ),
                                  Text(
                                    'Delete',
                                    style: TextStyle(
                                        fontSize: 16,
                                        color: Colors.red,
                                        fontWeight: FontWeight.w600),
                                  ),
                                ],
                              ),
                            )
                          ],
                        )
                      ],
                    ),
                  )
                ]);
              } else {
                return Center(
                  child: CircularProgressIndicator(),
                );
              }
            });
      }
    

    【讨论】:

    • 嗨,我应该在哪里编写将存储数据存储到 Firestore 的代码?
    • 您好,感谢您的回复。我应该在哪里添加这个?最终 FirebaseAuth _auth = FirebaseAuth.instance;最终用户用户 =_auth.currentUser;最终的 uid = user.uid; firestore.collection("TransactionExpense").doc(uid);并且在底部,updateData显示红线:“实例成员'updateData'无法使用静态访问'。如何解决?
    • 嗨,很抱歉这个错误,修复它:await DatabaseService().updateData(uid, date.text, amount.text, selectExpense, description.text);不要担心最终的 FirebaseAuth _auth = FirebaseAuth.instance;最终用户用户 =_auth.currentUser;最终的 uid = user.uid; firestore.collection("TransactionExpense").doc(uid);,我已将其包含在您的 onPressed 函数中。
    • 是的,它存储到数据库中,但它不是基于用户 ID。如果我用其他用户登录,数据仍然出现。知道如何解决吗?
    • 哦,很抱歉,我不知道您也想读取数据。为此添加了另一个代码块,试一试,让我知道它是否有效!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-07
    • 1970-01-01
    • 2018-11-02
    • 1970-01-01
    • 1970-01-01
    • 2021-09-10
    • 2016-04-02
    相关资源
    最近更新 更多