Skip to content
This repository was archived by the owner on Feb 23, 2026. It is now read-only.
This repository was archived by the owner on Feb 23, 2026. It is now read-only.

gRPC Async Helper seems incompatible when using firestore emulator #124

Description

@crwilcox

googleapis/python-firestore#286

While investigating the above issue, I think there may be an error in def _wrap_stream_errors. Specifically, under emulation call is never an instance of any of the specified types. However, if rather than raising a type error I retuern the call as is, just instantiating it, all seems to work as expected.

def _wrap_stream_errors(callable_):
    """Map errors for streaming RPC async callables."""
    grpc_helpers._patch_callable_name(callable_)

    @functools.wraps(callable_)
    async def error_remapped_callable(*args, **kwargs):

        call = callable_(*args, **kwargs)
        print(f"IN ASYNC REMAPPED CALLABLE {type(call)}")
        if isinstance(call, aio.UnaryStreamCall):
            call = _WrappedUnaryStreamCall().with_call(call)
        elif isinstance(call, aio.StreamUnaryCall):
            call = _WrappedStreamUnaryCall().with_call(call)
        elif isinstance(call, aio.StreamStreamCall):
            call = _WrappedStreamStreamCall().with_call(call)
        else:
            return call # NEW LINE
            #raise TypeError('Unexpected type of call %s' % type(call))

        await call.wait_for_connection()
        return call

    return error_remapped_callable

Also, it seems the sync method of this was changed in the same month. Is it possible the two implementations aren't a match? https://github.com/googleapis/python-api-core/blob/master/google/api_core/grpc_helpers.py#L132

Here is the code that will show sync working, but async failing.

import asyncio
from google.cloud.firestore import AsyncClient, Client
import os
import time

# ❯ gcloud beta emulators firestore start --host-port=localhost:8080
os.environ["FIRESTORE_EMULATOR_HOST"] = "localhost:8080"

async_client = AsyncClient()
client = Client()
document_name = f"test-{time.time()}"

async def document_set():
    client.collection("test").document("test_sync").set({"message": "Hello World!"})
  
    await async_client.collection("test").document(document_name).set({"message": "Hello World!"})
    doc = await async_client.collection("test").document(document_name).get()
    message = doc.get("message")
    print(f"Expect Hello World: {message}")


if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(document_set())

Metadata

Metadata

Assignees

Labels

priority: p2Moderately-important priority. Fix may not be included in next release.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions