vuejs / devtools-v6

⚙️ Browser devtools extension for debugging Vue.js applications.
https://devtools-v6.vuejs.org/
MIT License
24.66k stars 4.15k forks source link

Page reload hangs when Firestore DocumentReference is enumerable in vuex state #1154

Open mattnathan opened 4 years ago

mattnathan commented 4 years ago

Version

5.3.3

Browser and OS info

Chrome 79.0.3945.130 / Windows 10

Steps to reproduce

  1. Create a vue project that uses both vuex and Firebase.
  2. Add a DocumentReference to the store
  3. Open dev tools -> Vue -> Vuex and load the state
  4. Attempt to refresh the page

What is expected?

The page refreshes

What is actually happening?

The page hangs with a backwards spinner as the page never leaves itself. Eventually you get a Stack size exceeded error in the log.


I'm sorry, I couldn't figure out a way to create a reproducible project with all the correct libraries and auth details for Firebase.

mattnathan commented 4 years ago

I've just realised that this only happens with the new vuex backend enabled in settings

mattnathan commented 4 years ago

Anothing thing that I've noticed (while trying to deep clone the same object) - there are cyclic references in there somewhere. Maybe this issue is more about vuex devtools not supporting / handling cyclic references in the store gracefully during reload/unload?

dudintv commented 3 years ago

I have the same issue. The page goes to infinity reloading if I try to ".get()" collection from Firestore. Did you find out the solution?

mattnathan commented 3 years ago

I've created https://github.com/firebase/firebase-js-sdk/issues/4258 over at the firestore side to try and get it fixed at that end too.

I also dug into it a little more and this issue seems to only happen when the fast path JSON.stringify fails, typically due to circular references in firestore documents that are visible to vue/vuex (i.e. in state, returned from getters, passed to mutators, or as an event payload). In this case the vue dev tools falls back to a stringifyStrict internal implementation of JSON.stringify that tracks references to avoid cycles, but that is somehow less efficient than the built in stringify and regularly causes crashes in the dev tools due to out-of-memory exceptions.

The only work around I've found so far is to avoid/remove/hide these circular references from the enumerable properties that vue/vuex can see. I do this by redefining the property using Object.defineProperty(obj, 'ref', {enumerable: false, ...}) which stops the fast path JSON.stringify from failing.