posva / vuexfire

Check
https://github.com/vuejs/vuefire
MIT License
558 stars 49 forks source link

Firestore subcollection example using nested modules #167

Closed bdiz closed 6 years ago

bdiz commented 6 years ago

I'm unable to see how to create a Vuex nested module hierarchy that maps to firestore collections, doc, subcollection structure that is compatible with Vuexfire and bindFirebaseRef.

I think if I saw and example of adding sub-tasks to todos in the todo module example you have it would become clear.

What I can't wrap my head around is if I have a component the iterates all todos and their sub-tasks in the template, the sub-task subcollection ref is different for each todo and I don't know how to have Vuexfire listening for snapshots for all subcollections.

I'm setting my setTodosRef in a component created() hook and this is fine because there is only one todos firestore collection. This doesn't work for subcollections because there are many. If I looped over todos and called my setSubTasksRef() action, my understanding is each time I called bindFirebaseRef('subTasks', subTasksRef) it would unbind the previous leaving only the last todo with sub-tasks listening for snapshots.

What am I missing? Thanks.

posva commented 6 years ago

I'm unable to see how to create a Vuex nested module hierarchy that maps to firestore collections, doc, subcollection structure that is compatible with Vuexfire and bindFirebaseRef.

You cannot map a collection to a module and then a subcollection to a nested module with just a bindFirebaseRef.

Subcollections are not discoverable in the js sdk so there's no automatic binding. Currently there is no flexible way to add them either but it is planned: https://github.com/vuejs/vuefire/issues/153

bdiz commented 6 years ago

Ok. To me binding the subcollection refs manually would be just fine. In any case, I am unsure how to proceed with a relationship of todos with sub-tasks.

I can put sub-tasks as a top level collection and have a sub-task.todoId to associate them.

But I feel I'll still run into the issue of having multiple sub-task collection refs that want to bind to vuexfire through a single instance of my Vuex sub-task module.

Are there any examples of vuexfire usage with multiple root docs (ie todos) and their associations (ie sub-tasks) displayed at the same time (v-for in a v-for)?

posva commented 6 years ago

There's not any example with collection and subcollections yet. For the moment the api I was thinking about was only capable of embedding those subcollections inside of the document they belong to

bdiz commented 6 years ago

Is this the case for Vuefire as well? I haven't looked into Vuefire as much but I have a lot of deep associations for my intended purpose and I think my documents will become way too big/unmangeable.

posva commented 6 years ago

vuexfire and vuefire share the same codebase (as a copy at the moment but will share the exact same base in the future), so yes. Chim in into discussion and look at https://github.com/vuejs/vuefire/issues/153#issuecomment-358792109

To me, having a subcollection bound out of the original document is weird but nothing prevents you from doing so 🙂

bdiz commented 6 years ago

As collection and subcollection refs are so much the same I imagine, as you say, it wouldn't be a problem for vuexfire.

I guess the limitation I'm seeing is really in Vuex modules being there's a single instance of each module. We bind a todo collection ref to a todo module. This is fine because collection reference to module instance is one to one. We only want to render a single todos collection.

For a sub-task we have as many (sub)collection references as we do todo docs. As far as I can see, we'd need an instance of Vuex sub-task module per sub-task collection reference. In Vuex, there is one instance per module or nested module. And that to me is the fundamental problem. Do you agree?

posva commented 6 years ago

You don't need a module for every subcollection, put everything in the same module you put the todos collection, or if you really want to split that up, create a different module to contain all of them

bdiz commented 6 years ago

Ok, point taken. I think a single module would be fine for one level of subcollection. However, I feel like the module would become unwieldy after just 2+ subcollections of depth. For moderate to large sized collection hierarchies I'd think it'd need to be broken down for the same reasons the Single Responsibility Principle is used.

Perhaps dynamic modules is what I'm desiring/looking for to pair with subcollections. With a dynamic module I can instantiate a new copy of Vuex data for each todos sub-task subcollection I have. When I bind inside the dynamic module I'll need to do something like bindFirebaseRef('subTasks-${todoRef.id}', todoRef.collection("subTasks")).

Let me know if you disagree with my thinking. Thanks.