将文档数据检索到documentID与currentUser().uid相同的List中-Flutter [英] Retrieving documents data into a List where documentID is the same as currentUser().uid - Flutter

本文介绍了将文档数据检索到documentID与currentUser().uid相同的List中-Flutter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的CustomerNotifier类中有一个函数,该函数从Firebase读取所有客户,如下所示:

I had a function in my CustomerNotifier class that reads all customers as a list from Firebase as below:

  getCustomers(CustomerNotifier customerNotifier) async {
    String userId = (await FirebaseAuth.instance.currentUser()).uid;

    print('Current logged in user uid is: $userId');

    var snapshot = await customerCollection
        .orderBy('created_at', descending: true)
        .getDocuments();

    List<Customer> _customerList = [];

    snapshot.documents.forEach((document) {
      Customer customer = Customer.fromMap(document.data);
      _customerList.add(customer);
    });

    customerNotifier.customerList = _customerList;
  }

我还有另一个功能可以更新或创建新客户,并保存到Firebase中,如下所示:

I have another function to updates or creates a new customer and saves to Firebase as below:

Future updateCustomer(Customer customer, bool isUpdating) async {
    CollectionReference customerRef =
        await Firestore.instance.collection('customer');
    if (isUpdating) {
      customer.updatedAt = Timestamp.now();
      await customerRef.document().updateData(customer.toMap());
      print('updated customer with id: ${customer.id}');
    } else {
      customer.createdAt = Timestamp.now();

      DocumentReference documentReference =
          await customerRef.add(customer.toMap());

      customer.id = documentReference.documentID;

      print('created customer successfully with id: ${customer.id}');

      await documentReference.setData(customer.toMap(), merge: true);
      addCustomer(customer);
    }
    notifyListeners();
  }

使用上述两种方法,我曾经成功地将客户数据读取和写入Firebase.但是,我试图仅读取当前登录用户创建和更新的数据.因此,从其他stackoverflow线程的建议中,建议我将customer.id设置为userId,其中userId == currentUser().uid.我可以使用如下所示的updateCustomer的更新版本成功写入数据库:

With both methods above, I used to successfully read and write customer data to my Firebase. However, I am trying to only read data created and updated by the currently signed in User. So suggestions from other stackoverflow threads, I've been advised to set my customer.id to userId, where userId == currentUser().uid. I can successfully write to my DB using an updated version of my updateCustomer as below:

Future updateCustomer(Customer customer, bool isUpdating) async {
    CollectionReference customerRef =
        await Firestore.instance.collection('customer');
    FirebaseUser user = await FirebaseAuth.instance.currentUser();
    String userId = user.uid;
    print('Current logged in user uid is: $userId');

    if (isUpdating) {
      customer.updatedAt = Timestamp.now();
      await customerRef.document(userId).updateData(customer.toMap());
      print('updated customer with id: ${customer.id}');
    } else {
      customer.createdAt = Timestamp.now();

      DocumentReference documentReference = await customerRef.document(userId);
      // add(customer.toMap());

      customer.id = documentReference.documentID;

      print('created customer successfully with id: ${customer.id}');

      await documentReference.setData(customer.toMap(), merge: true);
      addCustomer(customer);
    }
    notifyListeners();
  }

由于documentID/customer.id现在等于登录的currentUser()的用户ID,如何继续从仅由currentUser()创建的Firebase读取客户数据?

How do I proceed to read customer data from firebase only created by currentUser() since documentID/customer.id is now equals to userId fo the currentUser() logged in?

这是到目前为止我尝试过的事情:

  getCustomers(CustomerNotifier customerNotifier) async {
String userId = (await FirebaseAuth.instance.currentUser()).uid;

print('Current logged in user uid is: $userId');

QuerySnapshot snapshot = await Firestore.instance
    .collection('customers')
    .where('id', isEqualTo: userId)
    .orderBy('created_at', descending: true)
    .getDocuments();

List<Customer> _customerList = [];

snapshot.documents.forEach((document) {
  Customer customer = Customer.fromMap(document.data);
  _customerList.add(customer);
});

customerNotifier.customerList = _customerList;
}

//customer_screen.dart //这使用ListView.builder来显示由currentUser()创建的所有客户

//customer_screen.dart //this uses a ListView.builder to display all customers created by currentUser()

class CustomersScreen extends StatefulWidget {
  static String id = 'customers';
    
  @override
  _CustomersScreenState createState() => _CustomersScreenState();
}
    
class _CustomersScreenState extends State<CustomersScreen> {

  bool showSpinner = true;
  bool _isInit = true;

  @override
  void initState() {
    if (_isInit) {
      showSpinner = true;
    } else {
      showSpinner = false;
    }
    CustomerNotifier customerNotifier =
        Provider.of<CustomerNotifier>(context, listen: false);
    customerNotifier.getCustomers(customerNotifier);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    CustomerNotifier customerNotifier = Provider.of<CustomerNotifier>(context);

    Future<void> _resfreshList() async {
      customerNotifier.getCustomers(customerNotifier);
    }

    return Scaffold(
      drawer: DrawerClass(),
      appBar: AppBar(
        title: Text(
          'All customers',
          style: kAppBarTextStyle,
        ),
        backgroundColor: kAppBarColour,
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          customerNotifier.currentCustomer = null;
          Navigator.of(context)
              .push(MaterialPageRoute(builder: (BuildContext context) {
            return CustomerFormScreen(isUpdating: false);
          }));
        },
        child: Icon(Icons.add),
        backgroundColor: kThemeIconColour,
      ),
      // body: showSpinner
      //     ? Center(child: CircularProgressIndicator())
      body: RefreshIndicator(
        child: Consumer<CustomerNotifier>(
          builder: (context, customer, child) {
            return customer == null
                ? Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    crossAxisAlignment: CrossAxisAlignment.center,
                    children: <Widget>[
                      PaddingClass(bodyImage: 'images/empty.png'),
                      SizedBox(
                        height: 20.0,
                      ),
                      Text(
                        'You don\'t have any customer',
                        style: kLabelTextStyle,
                      ),
                    ],
                  )
                : Padding(
                    padding: const EdgeInsets.only(top: 50.0),
                    child: ListView.separated(
                      itemBuilder: (context, int index) {
                        return Card(
                          margin: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 0.0),
                          elevation: 15.0,
                          color: Colors.white70,
                          child: Row(
                            crossAxisAlignment: CrossAxisAlignment.center,
                            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                            children: <Widget>[
                              Container(
                                height: 100.0,
                                child: Icon(
                                  FontAwesomeIcons.userCircle,
                                  color: kThemeIconColour,
                                  size: 50.0,
                                ),
                              ),
                              SizedBox(width: 20.0),
                              Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                mainAxisAlignment: MainAxisAlignment.center,
                                children: <Widget>[
                                  Text(' ${customer.customerList[index].firstName}' +
                                      '  ${customer.customerList[index].lastName}'),
                                  SizedBox(
                                    height: 8.0,
                                  ),
                                  Text(
                                      ' ${customer.customerList[index].phoneNumber}'),
                                  SizedBox(
                                    height: 8.0,
                                  ),
                                  Text(
                                      ' ${customer.customerList[index].email}'),
                                ],
                              ),
                              GestureDetector(
                                onTap: () {
                                  customerNotifier.currentCustomer =
                                      customerNotifier.customerList[index];
                                  Navigator.of(context).push(MaterialPageRoute(
                                      builder: (BuildContext context) {
                                    return CustomerDetailsScreen();
                                  }));
                                },
                                child: Icon(
                                  FontAwesomeIcons.caretDown,
                                  color: kThemeIconColour,
                                ),
                              ),
                            ],
                          ),
                        );
                      },
                      separatorBuilder: (BuildContext context, int index) {
                        return SizedBox(
                          height: 20.0,
                        );
                      },
                      itemCount: customerNotifier.customerList.length,
                    ),
                  );
          },
        ),
        onRefresh: _resfreshList,
      ),
    );
  }
}

谢谢.

推荐答案

在此处查看复合查询: https://firebase.google.com/docs /firestore/query-data/queries

Check out the compound queries here: https://firebase.google.com/docs/firestore/query-data/queries

特别是本节:

db.collection("cities").where("capital", "==", true)
    .get()
    .then(function(querySnapshot) {
        querySnapshot.forEach(function(doc) {
            // doc.data() is never undefined for query doc snapshots
            console.log(doc.id, " => ", doc.data());
        });
    })
    .catch(function(error) {
        console.log("Error getting documents: ", error);
    });

您可以使用此结构. 城市"是您的客户",资本"是您的客户"是文档上您另存为userIdWhenYouCreatedThisCustomerDocument的字段,而不是true,而是放置了当前用户ID.当然,它使用.then(),您可以执行此操作,也可以使用await将结果分配给变量.

You could use this structure. 'cities' is 'customer' for you, and "capital" is the field on your document that you've saved as userIdWhenYouCreatedThisCustomerDocument, and instead of true you'd put your current user id. Of course, this uses .then() and you could do that or assign the result to a variable using await.

我会注意到,您在阅读本文档时应仔细阅读文档,尤其是与使用用户ID进行子收集相比,这种方式尤为重要.哪一种都是正确的,但是如果您超出概念证明的范围,就会发现短语"where子句不是过滤器".在Firestore中考虑使用后一种方法是有原因的.当然,最后可能根本不重要.

I'll note that you should review the documentation as you work through this, particularly as it regards doing it this way vs. doing a subcollection by user ID. Either are correct, but if you go beyond a proof of concept you'll find the phrase "where clauses are not filters" in firestore to be a reason to consider the latter approach. Of course, that may not matter at all in the end.

根据新信息

为什么要使用QuerySnapshot? (当前)您正在为此获取文档快照,因此可以直接使用它.

Why are you using QuerySnapshot? You are (currently) retrieving a document snapshot for this, so you can use that directly.

或者,您可以发布您的Firestore的屏幕快照,并删除敏感数据吗?我想知道您是否打算将数据存储在用户文档中,就像立即检索查询代码期望按原样编写,而您的upsert代码交付一样,而不是将其存储在用户文档中的集合中. 如果是后者,则另一个答案中的代码可能对您和您当前的代码更好,因为它被设置为从集合而不是文档中读取.当然,这两种方法都可以工作.问题在于,现在您的增添内容和查询的前半部分正在执行前者,而在检索查询的一半过程中,您将切换到后者.

Alternatively, can you post a screenshot of your firestore, with senstive data removed? I'm wondering if you are intending to store your data in the user document, like the immediate retrieval query code expects as-written and your upsert code delivers, as opposed to storing it in a collection within your user document. If the latter, the code from the other answer would probably work better for you and your current code since it is set up to read from a collection, not a document. Of course, either approach could work just as well. The problem is that right now your upsert and the first half of your query is doing the former and halfway through your retrieval query you switch to the latter.

我认为您可以结合其他问题的答案(

I think you can combine the answer to your other question (Read data from Firebase created by loggedin user - Flutter) with the documentation to find your solution here.

此版本使用的Firestore版本比您使用的最新,但提供了一个很好的起点. https://firebase.google.com/docs/firestore/query-数据/获取数据

This uses a more up to date version of firestore than you're using, but provides a good starting point. https://firebase.google.com/docs/firestore/query-data/get-data

例如.

    DocumentReference ref =
    Firestore.instance.collection('YourCollectionNameInFireStore').document(user.uid);
    var temp = await docRef.getDocument();
    // do something with the data if you want.. not sure of syntax for old version on 
    // this, for new version it is .data()
    temp.data.<field>

这篇关于将文档数据检索到documentID与currentUser().uid相同的List中-Flutter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆