Vuefire: References in array item properties are lost when updating any field in a document

Created on 29 Jan 2020  路  10Comments  路  Source: vuejs/vuefire

Hi, I'm having a problem with the loss of references when I update any value within the document. It's similar to bug #325, but this time it happens in the reference inside array item properties:

Captura de tela de 2020-01-28 20-16-46

The references are loaded normally, but when I try to update any document property, the reference inside the array item property becomes a String instead of an object.

Captura de tela de 2020-01-28 20-42-54

As well as in the bug #325, If I re-bind the object, everything is fine.

bug contribution welcome firestore

Most helpful comment

The problem is probably somewhere here:
https://github.com/vuejs/vuefire/blob/2ce789c850f46358f41948432023f7daea990478/packages/%40posva/vuefire-core/src/firestore/utils.ts#L70-L76

In line 75, if newRef is an Object containing refs, nothing happens and refs aren't extracted, since newRef.path is undefined.

I still couldn't get my way around how recursiveExtract works, but if anyone finds out how to reprocess the whole object instead of just trying to get the path, pls share.

Also, I wrote a test in Refs Documents Spec to test this. If it can help anyone find the solution, that's the code:

// packages/@posva/vuefire-core/__tests__/firestore/refs-documents.spec.ts
  it('does not lose empty references in arrays of objects when updating a property', async () => {
    const emptyItem = collection.doc()
    await item.update({ todos: [{ ref: emptyItem }], toggle: true })
    await bind('item', item)
    expect(vm.item).toEqual({
      todos: [{ ref: null }],
      toggle: true,
    })
    await item.update({ toggle: false })
    expect(vm.item).toEqual({
      todos: [{ ref: null }],
      toggle: false,
    })
  })

All 10 comments

@posva I saw that you solved the issue #325, I imagine this bug is similar.

I tried to reproduce and I couldn't at https://github.com/vuejs/vuefire/blob/master/packages/vuefire/examples/index.html

  • Added an array of references of users to config named users
  • Added a reference inside of one of the users to a /todos/1
  • Updated the user containing the reference

I would need more info or a boiled down repro. One thing that looks weird in your log is the empty array

Is not a array of references, but a array of objects (maps) with references within.
I understood the problem with my log, it was not very clear. I reproduced the problem on a CodePen:
https://codepen.io/dbarjs/pen/RwNmBEB?editors=1010

  • The example database has the following structure:
    Captura de tela de 2020-01-29 18-01-14

  • In the first rendering, everything works as expected:
    Captura de tela de 2020-01-29 18-00-16

  • The problem happens when you update the title value:
    Captura de tela de 2020-01-29 18-00-28

I ran into this same issue. Here's my sample: https://jsfiddle.net/61ct7xbp/57/

Thanks, now it makes sense. I will probably not be able to give this a look until a few weeks but I think the error might come from some shared references that shouldn't be shared or be similar to #325. Maybe this gives someone the opportunity to give it a look before I can

@posva Thanks for understanding.
I have no experience with vuefire-core, but I will try to look for some solution to the issue. I don't guarantee anything, but I'll try. :)


For now, I'm solving the problem by making a new bind after the update:
Captura de tela de 2020-01-31 00-24-54

The problem is probably somewhere here:
https://github.com/vuejs/vuefire/blob/2ce789c850f46358f41948432023f7daea990478/packages/%40posva/vuefire-core/src/firestore/utils.ts#L70-L76

In line 75, if newRef is an Object containing refs, nothing happens and refs aren't extracted, since newRef.path is undefined.

I still couldn't get my way around how recursiveExtract works, but if anyone finds out how to reprocess the whole object instead of just trying to get the path, pls share.

Also, I wrote a test in Refs Documents Spec to test this. If it can help anyone find the solution, that's the code:

// packages/@posva/vuefire-core/__tests__/firestore/refs-documents.spec.ts
  it('does not lose empty references in arrays of objects when updating a property', async () => {
    const emptyItem = collection.doc()
    await item.update({ todos: [{ ref: emptyItem }], toggle: true })
    await bind('item', item)
    expect(vm.item).toEqual({
      todos: [{ ref: null }],
      toggle: true,
    })
    await item.update({ toggle: false })
    expect(vm.item).toEqual({
      todos: [{ ref: null }],
      toggle: false,
    })
  })

Thanks @trickstival for wrote the test, this is helping a lot!
It was possible to correct the bug by simply changing the parameter data[key] to oldDoc[key] of the line 78:
https://github.com/vuejs/vuefire/blob/2ce789c850f46358f41948432023f7daea990478/packages/%40posva/vuefire-core/src/firestore/utils.ts#L70-L78
Like this:

recursiveExtract(ref, oldDoc[key], path + key + '.', [data[key], refs]);

But unfortunately, the test "item should be removed from binding when theres an arrays of refs" receives an error. If you keep the data[key] parameter, the problem will happen in that part:
https://github.com/vuejs/vuefire/blob/2ce789c850f46358f41948432023f7daea990478/packages/%40posva/vuefire-core/src/firestore/utils.ts#L79-L81
A conflict probably occurs when the function tries to change the value of data[key]. After that, it is not possible to try to extract the reference data inside the object, as the oldDoc is empty:
https://github.com/vuejs/vuefire/blob/2ce789c850f46358f41948432023f7daea990478/packages/%40posva/vuefire-core/src/firestore/utils.ts#L64-L69

The test will be enough for simple cases but I imagine there are some cases that might not be covered when arrays contain nested values. Let me know if you find new problems

@dbarjs did this fix it for you? I'm running into this in a new project today and wondering if it ever got working for you.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

calirails picture calirails  路  5Comments

KMolendijk picture KMolendijk  路  3Comments

joelxr picture joelxr  路  3Comments

ConnerFrancis picture ConnerFrancis  路  6Comments

torfeld6 picture torfeld6  路  4Comments