【问题标题】:Get realtime updates with Cloud Firestore with asyncio使用带有 asyncio 的 Cloud Firestore 获取实时更新
【发布时间】:2021-03-22 00:37:45
【问题描述】:

如何通过 asyncio 运行这个 example?我在启动时遇到的错误:

name col_snapshot is not defined

样本:

    async def on_snapshot(col_snapshot, changes, read_time):
         logger.debug('Received updates')

    col_query = db.collection(u'cities')
    query_watch = col_query.on_snapshot(await on_snapshot(col_snapshot, changes, read_time))

更新:Async callbacks example

import os
import asyncio

from loguru import logger
from google.cloud.firestore import Client

os.environ['GOOGLE_APPLICATION_CREDENTIALS']='E:/Python/listener_firebase/creds.json'

async def callback(col_snapshot, changes, read_time):
    logger.debug('Received updates')

    for change in changes:
        if change.type.name == 'ADDED':
            logger.debug(f'New document: {change.document.id}')

    await asyncio.sleep(1)
    logger.debug('Finished handling the updates')

Client().collection('cities').on_snapshot(callback)

while True:
    pass

这对我不起作用:

tch.py:568: RuntimeWarning: coroutine 'callback' was never awaited
  self._snapshot_callback(keys, appliedChanges, read_time)
RuntimeWarning: Enable tracemalloc to get the object allocation traceback

【问题讨论】:

  • 您是否尝试过使用Documentation example 使用threading
  • on_snapshot 不做任何异步操作,因此将其定义为协程确实没有意义,但如果您正在做一些上面没有包含的事情,解决方法是您需要拨打on_snapshot:await on_snaphost(arg1, arg2, arg3)
  • @dirn 如果我使用query_watch = col_query.on_snapshot(await on_snapshot(col_snapshot, changes, read_time)) 然后我得到NameError: name 'col_snapshot' is not defined
  • 需要先定义变量才能使用。
  • @dirn 但在示例中,它们是隐式传递的。我怎样才能得到它们?

标签: python firebase google-cloud-firestore python-asyncio


【解决方案1】:

正如它所写的那样,您的代码根本不应该使用 asyncio。但是,如果 await asyncio.sleep(1) 是用来模拟一些利用 asyncio 的 I/O 繁重的代码,那么您的选择就不是很好。第一个解决方案是为 Firestore 使用异步感知客户端。我不知道是否存在。假设没有,并且正如您所说,您需要使用已经在运行的事件循环,您需要定义一个同步函数(因为这需要传递给客户端的on_snapshot)来安排您的异步使用事件循环回调。

import os
import asyncio

from loguru import logger
from google.cloud.firestore import Client

os.environ['GOOGLE_APPLICATION_CREDENTIALS']='E:/Python/listener_firebase/creds.json'

async def asynchronous_callback(changes):
    logger.debug('Received updates')

    for change in changes:
        if change.type.name == 'ADDED':
            logger.debug(f'New document: {change.document.id}')

    await asyncio.sleep(1)
    logger.debug('Finished handling the updates')

def synchronous_callback(col_snapshot, changes, read_time):
    asyncio.create_task(asynchronous_callback(changes))

Client().collection('cities').on_snapshot(synchronous_callback)

while True:
    pass

实际上,您最好的选择是不要将 asyncio 用于您的回调,因为 Firestore 客户端已经在同步运行您的代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-14
    • 2018-08-01
    • 2020-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多