Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error in onSnapshot: FirebaseError: [code=invalid-argument]: transaction closed

I'm recursively loading a tree stored in Firestore. The tree has ~79 nodes.

Very occasionally I'm getting this error (about one in ten full-tree loads).

Edit: the code: https://github.com/karol-depka/OrYoL

Edit: the example deployed: https://oryol.karoldepka.com/tree (sorry, no plunker for now, just this)

Details below.

Firebase version in package.json: 4.5.0

Questions:

Where can I get more info than this basic documentation https://firebase.google.com/docs/reference/js/firebase.FirebaseError ?

What is the source of the problem and how to fix it?

3VM724:27 Uncaught Error in onSnapshot: Error: transaction closed
at new FirestoreError (error.js:164)
at JsonProtoSerializer.webpackJsonp.../../../../firebase/firestore/remote/serializer.js.JsonProtoSerializer.fromRpcStatus (serializer.js:126)
at JsonProtoSerializer.webpackJsonp.../../../../firebase/firestore/remote/serializer.js.JsonProtoSerializer.fromWatchChange (serializer.js:517)
at PersistentListenStream.webpackJsonp.../../../../firebase/firestore/remote/persistent_stream.js.PersistentListenStream.onMessage (persistent_stream.js:334)
at persistent_stream.js:270
at persistent_stream.js:247
at async_queue.js:81
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:392)
at Object.onInvoke (core.es5.js:3890)
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:391)

The code:

private processNodeEvents(nestLevel: number, snapshot: any, parents, listener: DbTreeListener) {
  const serviceThis = this
  snapshot.docChanges.forEach(function(change) {
    let data = change.doc.data()
    if (change.type === 'added') {
      const parentsPath = serviceThis.nodesPath(parents)
      console.log('node: ', nestLevel, parentsPath, data);
      serviceThis.pendingListeners ++
      data.node.onSnapshot(targetNodeDoc => {
        serviceThis.pendingListeners --
        listener.onNodeAdded(
          new NodeAddEvent(parentsPath, parentsPath[parentsPath.length - 1], targetNodeDoc, targetNodeDoc.id,
            serviceThis.pendingListeners))
        console.log('target node:', nestLevel, targetNodeDoc)
        console.log('target node title:', nestLevel, targetNodeDoc.data().title)

        const subCollection = targetNodeDoc.ref.collection('subNodes')
        console.log('subColl:', subCollection)
        subCollection.onSnapshot((subSnap: QuerySnapshot) => {
          const newParents = parents.slice(0)
          newParents.push(targetNodeDoc.ref)
          serviceThis.processNodeEvents(nestLevel + 1, subSnap, newParents, listener)
        })
      })
      // console.log('root node ref: ', targetNode);
    }
    if (change.type === 'modified') {
      console.log('Modified city: ', data);
    }
    if (change.type === 'removed') {
      console.log('Removed city: ', data);
    }
  })
}

Edit: another error discovered, by running the code multiple times:

VM3343:27 Uncaught Error in onSnapshot: Error: The referenced transaction has expired or is no longer valid.
at new FirestoreError (error.js:164)
at JsonProtoSerializer.webpackJsonp.../../../../firebase/firestore/remote/serializer.js.JsonProtoSerializer.fromRpcStatus (serializer.js:126)
at JsonProtoSerializer.webpackJsonp.../../../../firebase/firestore/remote/serializer.js.JsonProtoSerializer.fromWatchChange (serializer.js:517)
at PersistentListenStream.webpackJsonp.../../../../firebase/firestore/remote/persistent_stream.js.PersistentListenStream.onMessage (persistent_stream.js:334)
at persistent_stream.js:270
at persistent_stream.js:247
at async_queue.js:81
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:392)
at Object.onInvoke (core.es5.js:3890)
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:391)
window.console.error @ VM3343:27

Edit: update firebase to 4.6.0, problem happened 3 times:

Uncaught Error in onSnapshot: Error: transaction closed
  at new FirestoreError (error.js:149)
  at JsonProtoSerializer.webpackJsonp.../../../../@firebase/firestore/dist/esm/src/remote/serializer.js.JsonProtoSerializer.fromRpcStatus (serializer.js:93)
  at JsonProtoSerializer.webpackJsonp.../../../../@firebase/firestore/dist/esm/src/remote/serializer.js.JsonProtoSerializer.fromWatchChange (serializer.js:536)
  at PersistentListenStream.webpackJsonp.../../../../@firebase/firestore/dist/esm/src/remote/persistent_stream.js.PersistentListenStream.onMessage (persistent_stream.js:309)
  at persistent_stream.js:246
  at persistent_stream.js:222
  at async_queue.js:62
  at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:392)
  at Object.onInvoke (core.es5.js:3890)
  at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:391)

Edit: even if the error happens, the tree seems to continue loading.

Edit: another version of the error, with code=aborted (after upgrading firebase to 4.6.0):

Error in onSnapshot: FirebaseError: [code=aborted]: The referenced transaction has expired or is no longer valid.
/vendor.bundle.js:18588 errHandler()
/vendor.bundle.js:33367
/polyfills.bundle.js:2970 ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask()
/vendor.bundle.js:107276 Object.onInvokeTask()
/polyfills.bundle.js:2969 ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask()
/polyfills.bundle.js:2737 Zone.webpackJsonp.../../../../zone.js/dist/zone.js.Zone.runTask()
/polyfills.bundle.js:3044 webpackJsonp.../../../../zone.js/dist/zone.js.ZoneTask.invokeTask()
/polyfills.bundle.js:3033 ZoneTask.invoke()
like image 594
KarolDepka Avatar asked Oct 22 '17 17:10

KarolDepka


People also ask

How do I use getDoc for firestore?

Firebase 9 Firestore Get A Document By ID Using getDoc() Let's get the first document of the cities collection by id. Import Firestore Database and de-structure the three methods that we need: getFirestore() → Firestore Database. doc() → It takes references of database, collection name and ID of a document as arguments.

How do I get data from firestore Android Kotlin?

You need to create reference of the firestore database. Then get the data from the collection and this will return you all the documents of a collection. In iteration convert the documents to the user class that you need to create which will have email field.


1 Answers

I have more or less the same and it is random when it works and don't. I don't use snapshot, but valueChanges

ERROR Error: transaction closed
at new FirestoreError (error.js:149)
at JsonProtoSerializer.webpackJsonp.../../../../@firebase/firestore/dist/esm/src/remote/serializer.js.JsonProtoSerializer.fromRpcStatus (serializer.js:93)
at JsonProtoSerializer.webpackJsonp.../../../../@firebase/firestore/dist/esm/src/remote/serializer.js.JsonProtoSerializer.fromWatchChange (serializer.js:536)
at PersistentListenStream.webpackJsonp.../../../../@firebase/firestore/dist/esm/src/remote/persistent_stream.js.PersistentListenStream.onMessage (persistent_stream.js:309)
at persistent_stream.js:246
at persistent_stream.js:222
at async_queue.js:62
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:392)
at Object.onInvoke (core.es5.js:3890)
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:391)

For me it's this peace of code that provokes the error:

return Observable.forkJoin(entries.map(entry => {
  return this.getPick(entry)
}))

each entry in entries is used to return a single pick from firestore.

  private getPick(entryId: number) {
     return this.afs.collection<Pick>('entry/' + entryId + '/event/' + '9/' + 'picks', ref => ref.where('is_captain','==',true))
     .valueChanges()

I don't mean to hijack your thread, but I feel this is very relevant. If I change the forkJoin to

Observable.forkJoin(entries.slice(0,20)...

then it works, so I guess it is some kind of overload of queries.

like image 110
Pål Skønberg Løvik Avatar answered Oct 04 '22 17:10

Pål Skønberg Løvik