1

I have two collections in firestore db 1. projects 2.users

'projects' has a field 'created_by' which hold the id of the user who created it. I want to fetch projects along with all fields of the user who created it.

Following code works but I am not sure whether it is the correct way of doing this and how do we know when the fetching of user data for every project is complete.

fun getProjects(){

    val works = arrayListOf<Work>()
    db.collection("projects")
        .get()
        .addOnSuccessListener { documents ->
            for (document in documents) {

                val work = Work(document.id,
                    document.data.get("title").toString(),
                    document.data.get("skills") as ArrayList<String>,
                    document.data.get("date_created") as Date)

                works.add(work)

                db.collection("users").document(document.data.get("created_by").toString()).get()
                    .addOnSuccessListener {
                        documentSnapshot ->
                            work.created_by = User(documentSnapshot.data?.get("name").toString(),
                                    documentSnapshot.data?.get("mob").toString(),
                                    documentSnapshot.data?.get("role").toString(),
                                    documentSnapshot.data?.get("rating").toString(),
                                    documentSnapshot.data?.get("skills") as ArrayList<String>
                                    )
                        Log.d("works", works.toString())

                    }
            }
        }
        .addOnFailureListener { exception ->
            Log.w(TAG, "Error getting documents: ", exception)
        }
}
bhanu agrawal
  • 19
  • 2
  • 6

1 Answers1

2

If the code works for your use-cases, it is probably the right approach for you. Since Firestore doesn't support server-side joins, doing this client-side join is a common approach.

A few considerations though:

  1. You're using a get to get both the projects and the users, which means you get the data only once. There is no problem with that, but I always recommend double-checking if you shouldn't listen for real time updates. There's no hard rule on when this is better, so just consider what the advantages and disadvantages for your users and codebase may be.

  2. Consider how much user data you really need, and whether it's worth it to duplicate this user data that you need under each project. If you duplicate the data, you won't need to perform the nested reads/client-side join. You're essentially storing more data, and complicating your write operations, to get a more scaleable read operation, and simpler code there.

When you new to NoSQL it is often hard to get to grips with the new data model. In that case I recommend checking out:

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807