【问题标题】:SQL like joins in Firestore类似于 Firestore 中的 SQL 连接
【发布时间】:2020-12-17 07:38:59
【问题描述】:

我在 Cloud Firestore 中有一个名为 creditcards 的集合和一个名为 ownedcreditcards 的集合。我想执行一个查询,在其中加入两个集合以仅查找存在于creditcards-collection 中的信用卡,而不是存在于ownedcreditcards 中的信用卡。据我了解,Firestore 中不存在类似 JOINS 的 SQL,您必须在多个查询中检索数据。我试图在我的两个集合上调用getAll()-functions(它检索所有文档),将数据临时存储在两个ArrayLists 中,然后将这两个列表相互比较。但是我尝试将数据存储在ArrayList 中的尝试没有成功,因为当我尝试LOG 时它返回空。
如何将我的两个集合中的数据存储在 ArrayList 中,或者有更简单的方法吗?

creditcards-collection 包含以下字段:

  • 身份证
  • 姓名
  • 提供者

ownedcreditcards-collection 包含以下字段:

  • 身份证
  • 信用卡号
  • 信用卡名称
  • 昵称
  • 用户名


ActivityStore 类的代码对于 usercreditcardcreditcard 或多或少相同。下面是usercreditcard的代码。

UserCreditCardActivity.kt

val arrayList = ArrayList<Any>()

    private fun retrieveCards() {
    val userCreditcard = UserCardStore()
    userCreditcard.getAll(object : Callback<UserCardModel> {
        override fun onCallback(list: List<UserCardModel>) {
            for (card in list) {
                adapter.add(UserCardItem(card)) //this works
                arrayList.add(card) //this doesnt work as when I print the list it returns empty
            }
        }
    })
}

UserCardStore.kt

    override fun getAll(myCallback: Callback<UserCardModel>) {
    auth = FirebaseAuth.getInstance()
    documentdata.whereIn("userid", listOf(auth.uid))
       .get().addOnCompleteListener { task ->
        if (task.isSuccessful) {
            val list = ArrayList<UserCardModel>()
            for (document in task.result!!) {
                val usercard = document.toObject(UserCardModel::class.java)
                list.add(usercard)
            }
            myCallback.onCallback(list)
        }
    }
}

【问题讨论】:

    标签: android firebase kotlin google-cloud-firestore


    【解决方案1】:

    据我了解,像 JOINS 这样的 SQL 在 Firestore 中不存在,您必须在多个查询中检索数据。

    是的,没错,Cloud Firestore支持“JOIN”类型的操作。 Firestore 查询一次只能从一个集合中获取文档。如果您需要从两个集合中获取数据并将结果添加到列表中,则必须执行两个不同的查询。

    解决这个问题的关键是尝试仅在第一个查询完成时才获得第二个查询的结果。在代码中,这些查询应如下所示:

    creditcardsRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
        @Override
        public void onComplete(@NonNull Task<QuerySnapshot> task) {
            if (task.isSuccessful()) {
                List<UserCardModel> userCardList = new ArrayList<>();
                for (QueryDocumentSnapshot document : task.getResult()) {
                    userCardList.add(document.toObject(UserCardModel.class));
    
                    ownedcreditcardsRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                        @Override
                        public void onComplete(@NonNull Task<QuerySnapshot> task) {
                            if (task.isSuccessful()) {
                                for (QueryDocumentSnapshot doc : task.getResult()) {
                                    userCardList.add(doc.toObject(UserCardModel.class));
                                }
    
                                //Do what you need to do with the list
                            } else {
                                Log.d(TAG, "Error getting documents: ", task.getException());
                            }
                        }
                    });
                }
            } else {
                Log.d(TAG, "Error getting documents: ", task.getException());
            }
        }
    });
    

    但是,这种方法可能会被认为有点昂贵,因为您总是阅读两个集合的内容。您有一个可能的替代方法是引入第三个集合,其中数据已经从两个集合中“加入”。这种做法称为非规范化,是 Firebase 的常见做法。为了更好地理解,我建议您观看此视频,Denormalization is normal with the Firebase Database。它适用于 Firebase 实时数据库,但同样的规则适用于 Cloud Firestore。

    【讨论】:

    • 谢谢你,这对我有帮助!我也会看视频的
    猜你喜欢
    • 1970-01-01
    • 2020-12-29
    • 1970-01-01
    • 2015-12-12
    • 2021-09-23
    • 1970-01-01
    • 2013-09-28
    • 2016-08-28
    • 1970-01-01
    相关资源
    最近更新 更多