Firebase-tools: Firestore local emulator exception "call is closed"

Created on 4 Nov 2018  路  5Comments  路  Source: firebase/firebase-tools

Version info

6.0.1

Platform Information

Windows 10 latest and Mac latest

Steps to reproduce

Start up the local emulator: firebase serve --only firestore

Implement the code below in index.js or something, and run it once.

const firebase = require(`@firebase/testing`);
const app = firebase.initializeTestApp({
    projectId: `my-test-project`,
    auth: { uid: `alice`, email: `[email protected]` }
  })
const firebase = app.firebase()
async function start(){
await firebase.collection('users').add({name:'harry'}}
await firebase.collection('users').get()
}

start()

It will work the first time. Running add multiple times though will trigger a java exception in the Firestore emulator. Get requests seem to work fine, and running add does actually add to the local emulator, showing up in get afterward.

Expected behavior

I can see that the docs explicitly talk about using the emulator for testing firestore rules, but if this can also work for Server side applications using TDD, and, hopefully, eventually front-end apps, it'd really be a big help for local development.

Expected behavior is that it should not crash and continue working for server app development using Google Cloud Firestore.

I can get around this by restarting the firestore emulator, but, again, the .add function will only resolve once before triggering again.

Actual behavior

The second run of the .add() method hangs indefinitely and never resolves while the emulator throws the error below.

Stack trace
firestore: Nov 04, 2018 1:50:03 PM io.grpc.internal.SerializingExecutor run SEVERE: Exception while executing runnable io.grpc.internal.ServerImpl$JumpToApplicationThreadServerStreamListener$1MessagesAvailable@1459d38 java.lang.IllegalStateException: call is closed at com.google.common.base.Preconditions.checkState(Preconditions.java:507) at io.grpc.internal.ServerCallImpl.sendMessage(ServerCallImpl.java:129) at io.grpc.stub.ServerCalls$ServerCallStreamObserverImpl.onNext(ServerCalls.java:341) at com.google.cloud.datastore.emulator.impl.util.WrappedStreamObserver.onNext(WrappedStreamObserver.java:26) at com.google.cloud.datastore.emulator.impl.CloudFirestoreV1ListenStream.notifyReset(CloudFirestoreV1ListenStream.java:123) at com.google.cloud.datastore.emulator.impl.watch.ListenStreamManager.notifyQueryListeners(ListenStreamManager.java:204) at com.google.cloud.datastore.emulator.impl.watch.ListenStreamManager.notifyListeners(ListenStreamManager.java:72) at com.google.cloud.datastore.emulator.impl.CloudFirestoreV1.internalCommit(CloudFirestoreV1.java:466) at com.google.cloud.datastore.emulator.impl.CloudFirestoreV1.write(CloudFirestoreV1.java:399) at com.google.cloud.datastore.emulator.impl.CloudFirestoreV1WriteStream.handleRequest(CloudFirestoreV1WriteStream.java:209) at com.google.cloud.datastore.emulator.impl.CloudFirestoreV1WriteStream.write(CloudFirestoreV1WriteStream.java:136) at com.google.cloud.datastore.emulator.impl.CloudFirestoreV1WriteStream.onNext(CloudFirestoreV1WriteStream.java:92) at com.google.cloud.datastore.emulator.impl.CloudFirestoreV1WriteStream.onNext(CloudFirestoreV1WriteStream.java:25) at io.grpc.stub.ServerCalls$StreamingServerCallHandler$StreamingServerCallListener.onMessage(ServerCalls.java:248) at io.grpc.ForwardingServerCallListener.onMessage(ForwardingServerCallListener.java:33) at io.grpc.Contexts$ContextualizedServerCallListener.onMessage(Contexts.java:76) at io.grpc.ForwardingServerCallListener.onMessage(ForwardingServerCallListener.java:33) at io.grpc.Contexts$ContextualizedServerCallListener.onMessage(Contexts.java:76) at io.grpc.internal.ServerCallImpl$ServerStreamListenerImpl.messagesAvailable(ServerCallImpl.java:263) at io.grpc.internal.ServerImpl$JumpToApplicationThreadServerStreamListener$1MessagesAvailable.runInContext(ServerImpl.java:686) at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37) at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:123) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source)

Most helpful comment

Diagnosed and fixed. The next release will no longer have this behavior. I will keep this issue open until that release is shipped.

All 5 comments

Your repro doesn't run for me.

const firebase = app.firebase()
      ^

SyntaxError: Identifier 'firebase' has already been declared

I've seen this "call is closed" error before. It happens when the client disconnects uncleanly. Could you provide a working version of your code so I can get a better idea what's going on?

Nevermind, I can reproduce what you're describing. There's some issue with the

await firebase.collection('users').get()

not closing properly. I'll investigate further and update this issue when I have a fix.

Apologies, I just kind of write out the code in the issue.

Diagnosed and fixed. The next release will no longer have this behavior. I will keep this issue open until that release is shipped.

Version 6.1.0 should resolve this issue.

Was this page helpful?
0 / 5 - 0 ratings