Skip to content

Commit 6e1f56f

Browse files
committed
feat: support timestamps (Firestore 4.13.0)
Closes #181
1 parent 8ed95ab commit 6e1f56f

File tree

4 files changed

+75
-30
lines changed

4 files changed

+75
-30
lines changed

examples/index.html

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
<head>
55
<meta charset="utf-8">
66
<title>VueFire Todo App Demo</title>
7-
<script src="https://www.gstatic.com/firebasejs/4.6.0/firebase.js"></script>
8-
<script src="https://www.gstatic.com/firebasejs/4.6.0/firebase-firestore.js"></script>
7+
<script src="https://www.gstatic.com/firebasejs/4.13.0/firebase.js"></script>
8+
<script src="https://www.gstatic.com/firebasejs/4.13.0/firebase-firestore.js"></script>
99
<script src="https://unpkg.com/vue"></script>
1010
<script src="../dist/vuefire.js"></script>
1111
</head>
@@ -64,6 +64,7 @@ <h5>Original data</h5>
6464
databaseURL: 'https://vue-fire-store.firebaseio.com'
6565
})
6666
const db = firebase.firestore()
67+
db.settings({ timestampsInSnapshots: true })
6768
const todos = db.collection('todos')
6869
const unFinishedTodos = todos.where('finished', '==', false)
6970
const finishedTodos = todos.where('finished', '==', true)

src/utils.js

+12-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@ function isObject (o) {
99
return o && typeof o === 'object'
1010
}
1111

12+
function isTimestamp (o) {
13+
return o.toDate
14+
}
15+
16+
function isRef (o) {
17+
return o && o.onSnapshot
18+
}
19+
1220
export function extractRefs (doc, oldDoc, path = '', result = [{}, {}]) {
1321
// must be set here because walkGet can return null or undefined
1422
oldDoc = oldDoc || {}
@@ -19,7 +27,7 @@ export function extractRefs (doc, oldDoc, path = '', result = [{}, {}]) {
1927
return Object.keys(doc).reduce((tot, key) => {
2028
const ref = doc[key]
2129
// if it's a ref
22-
if (ref && typeof ref.isEqual === 'function') {
30+
if (isRef(ref)) {
2331
tot[0][key] = oldDoc[key] || ref.path
2432
// TODO handle subpathes?
2533
tot[1][path + key] = ref
@@ -28,8 +36,10 @@ export function extractRefs (doc, oldDoc, path = '', result = [{}, {}]) {
2836
tot[0][key] = Array(ref.length).fill(null)
2937
extractRefs(ref, oldDoc[key], path + key + '.', [tot[0][key], tot[1]])
3038
} else if (
31-
ref instanceof Date ||
3239
ref == null ||
40+
// Firestore < 4.13
41+
ref instanceof Date ||
42+
isTimestamp(ref) ||
3343
(ref.longitude && ref.latitude) // GeoPoint
3444
) {
3545
tot[0][key] = ref

test/helpers/mock.js

+48-25
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,22 @@ export class GeoPoint {
1111
return this._long
1212
}
1313
}
14+
15+
export class Timestamp {
16+
constructor (seconds, nanoseconds) {
17+
this.seconds = seconds
18+
this.nanoseconds = nanoseconds
19+
}
20+
21+
toDate () {
22+
return new Date(this.toMillis())
23+
}
24+
25+
toMillis () {
26+
return this.seconds * 1000 + this.nanoseconds / 1e6
27+
}
28+
}
29+
1430
export class DocumentSnapshot {
1531
constructor (firestore, key, document, exists) {
1632
this._firestore = firestore
@@ -63,9 +79,7 @@ class callbacksAndErrors {
6379
}
6480

6581
_callCallbacks (data) {
66-
Object.values(this.cbs).forEach(
67-
cb => cb(data)
68-
)
82+
Object.values(this.cbs).forEach(cb => cb(data))
6983
}
7084
}
7185

@@ -148,12 +162,14 @@ class CollectionReference extends callbacksAndErrors {
148162
index: Object.keys(this.data).length
149163
})
150164
this._callCallbacks({
151-
docChanges: [{
152-
type: 'added',
153-
doc: new DocumentSnapshot(null, id, data),
154-
newIndex: Object.keys(this.data).length - 1,
155-
oldIndex: -1
156-
}]
165+
docChanges: [
166+
{
167+
type: 'added',
168+
doc: new DocumentSnapshot(null, id, data),
169+
newIndex: Object.keys(this.data).length - 1,
170+
oldIndex: -1
171+
}
172+
]
157173
})
158174
return this.data[id.v]
159175
}
@@ -163,22 +179,27 @@ class CollectionReference extends callbacksAndErrors {
163179

164180
doc (id) {
165181
id = new Key(id)
166-
return this.data[id.v] || new DocumentReference({
167-
collection: this,
168-
id,
169-
data: {},
170-
index: Object.keys(this.data).length
171-
})
182+
return (
183+
this.data[id.v] ||
184+
new DocumentReference({
185+
collection: this,
186+
id,
187+
data: {},
188+
index: Object.keys(this.data).length
189+
})
190+
)
172191
}
173192

174193
async _remove (id) {
175194
const ref = this.data[id.v]
176195
delete this.data[id.v]
177196
this._callCallbacks({
178-
docChanges: [{
179-
doc: new DocumentSnapshot(null, id, ref.data),
180-
type: 'removed'
181-
}]
197+
docChanges: [
198+
{
199+
doc: new DocumentSnapshot(null, id, ref.data),
200+
type: 'removed'
201+
}
202+
]
182203
})
183204
ref.collection = null
184205
ref.data = null
@@ -192,12 +213,14 @@ class CollectionReference extends callbacksAndErrors {
192213
type = 'added'
193214
}
194215
this._callCallbacks({
195-
docChanges: [{
196-
type,
197-
doc: new DocumentSnapshot(null, id, data),
198-
oldIndex: this.data[id.v].index,
199-
newIndex: this.data[id.v].index
200-
}]
216+
docChanges: [
217+
{
218+
type,
219+
doc: new DocumentSnapshot(null, id, data),
220+
oldIndex: this.data[id.v].index,
221+
newIndex: this.data[id.v].index
222+
}
223+
]
201224
})
202225
}
203226
}

test/utils.spec.js

+12-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { createSnapshot, extractRefs } from '../src/utils'
2-
import { Key, db, _id, DocumentReference, GeoPoint, DocumentSnapshot } from './helpers'
2+
import { Key, db, _id, DocumentReference, GeoPoint, DocumentSnapshot, Timestamp } from './helpers'
33

44
let id, doc, snapshot, collection, docRef
55
beforeEach(() => {
@@ -56,6 +56,17 @@ test('leave Date objects alone when extracting refs', () => {
5656
expect(refs).toEqual({})
5757
})
5858

59+
test('leave Timestamps objects alone when extracting refs', () => {
60+
const d = new Timestamp(10, 10)
61+
const [doc, refs] = extractRefs({
62+
foo: 1,
63+
bar: d
64+
})
65+
expect(doc.foo).toBe(1)
66+
expect(doc.bar).toBe(d)
67+
expect(refs).toEqual({})
68+
})
69+
5970
test('leave GeoPoint objects alone when extracting refs', () => {
6071
const d = new GeoPoint(2, 48)
6172
const [doc, refs] = extractRefs({

0 commit comments

Comments
 (0)