Make it easy to access the per item firebase refs.
If you add res['.ref'] = _getRef(snapshot) to the createRecord function. Like:
function createRecord (snapshot) {
var value = snapshot.val()
var res = isObject(value)
? value
: { '.value': value }
res['.key'] = _getKey(snapshot)
res['.ref'] = _getRef(snapshot);
return res
}
Then we can more easily access the firebase reference that is associated with a given item. The example in the readme could be changed from:
deleteItem: function (item) {
this.$firebaseRefs.items.child(item['.key']).remove()
}
to:
deleteItem: function (item) {
item['.ref'].remove()
}
mmh, this is interesting. Any situation when $firebaseRefs is not enough?
It's just easier access. Make the resulting user code much more readable IMHO.
oh wait, you're asking to add a ref for every single element? That is too much. I will have to think about it. I like how practical it is but it introduces other problems
would making it a function like: res['.ref'] = function() { return _getRef(snapshot); }
Help your concerns?
@posva any updates?
not yet, I'll look into this later
would making it a function like:
res['.ref'] = function() { return _getRef(snapshot); }Help your concerns?
@anachirino or it could be a getter with Object.defineProperty
function createRecord (snapshot) {
var value = snapshot.val()
var res
if (isObject(value)) {
res = value
} else {
res = {}
Object.defineProperty(res, '.value', {
value: value
})
}
Object.defineProperty(res, '.key', {
value: _getKey(snapshot)
})
Object.defineProperty(res, '.ref', {
get: function () {
return _getRef(snapshot)
}
})
return res
}
For the moment, this is now achievable with the serialize option (https://vuefire.vuejs.org/api/vuefire.html#options-serialize)
I was able to achieve the result by doing this in my main.js:
import { VueFire, VueFireAuth, globalFirestoreOptions, firestoreDefaultConverter } from 'vuefire'
globalFirestoreOptions.converter = {
// the default converter just returns the data: (data) => data
toFirestore: firestoreDefaultConverter.toFirestore,
fromFirestore: (snapshot, options) => {
const data = firestoreDefaultConverter.fromFirestore(snapshot, options)
// if the document doesn't exist, return null
if (!data) return null
// add anything custom to the returned object
// data.metadata = snapshot.metadata
data.ref = snapshot.ref
return data
},
}
note the line: data.ref = snapshot.ref
Sadly, it does not do the same for the referenced children which are loaded. Those end up not having a ref.
UPDATE: I later noticed that this also get's pushed to the firestore upon update. So it's not read only and I don't know how I would make it read only 🙈.
Use Object.defineProperty to make it non enumerable 😉
How does this work with TypeScript?
I have tried this without any luck.
globalFirestoreOptions.converter = {
// the default converter just returns the data: (data) => data
toFirestore: firestoreDefaultConverter.toFirestore,
fromFirestore: (snapshot, options) => {
const data = firestoreDefaultConverter.fromFirestore(snapshot, options);
// if the document doesn't exist, return null
if (!data) return null;
// add anything custom to the returned object
// Adding a ref (aka DocumentReference)
Object.defineProperty(data, "ref", {
value: snapshot.ref,
enumerable: false,
writable: true,
configurable: true,
});
return data as DocumentData & {
readonly id: string;
readonly ref: DocumentReference<DocumentData>;
};
},
};
The code works, because I can access ref on my useDocument objects. But TypeScript still complains with an error.
For example, when I try to access ref on a User document I get this TypeScript error: Property 'ref' does not exist on type 'User & { readonly id: string; }'. ts(2339)
Also I have noticed this does not work for useCollection(). It only works for useDocument().
When using useCollection() it would be good to have a collection reference on the collection itself, and a document reference stored on a ref property of on each document in the collection array.
For the moment, this is now achievable with the serialize option (https://vuefire.vuejs.org/api/vuefire.html#options-serialize)
For who is looking for the serialize option document, it is moved to here now.