【问题标题】:Cannot retrieve data from Firebase Real-time Database with JAVA Admin SDK using Event Listener无法使用事件侦听器通过 JAVA Admin SDK 从 Firebase 实时数据库中检索数据
【发布时间】:2021-09-02 06:27:30
【问题描述】:

我正在从具有数据库特权访问权限的 SpringBoot 应用程序访问 Firebase 实时数据库。这就是我们使用 JAVA Admin SDK 的原因。一切都已设置并正常工作。我们使用身份验证没有问题,并且存储数据也有效。问题在于使用ValueEventListener 检索数据。 onDataChange 事件根本不会执行。测试时,我设置了多个断点,但这些断点没有命中,也没有输出日志或打印语句。根据我对the docs 的了解,它至少应该使用初始数据调用一次,这就是我所需要的。

我们的 Springboot App 是用 Kotlin 编写的,相关代码在 getRelatedData() 函数中。插入按预期工作,我验证数据已正确插入。已经感谢您的帮助。

@Service
class AccountRelatedDataService(private val database: FirebaseDatabase) {

    fun insertRelatedData(accountRelatedData: AccountRelatedData) {
        val accountRelatedDataRef = database.getReference(refPath)
        accountRelatedDataRef.child(accountRelatedData.fireBaseUID).setValueAsync(accountRelatedData).get()
    }

    fun getRelatedData(accountRelatedData: AccountRelatedData) {
        val accountRelatedDataRef = database.getReference(refPath)

        val listener = object : ValueEventListener {

            @Override
            override fun onDataChange(dataSnapshot: DataSnapshot) {
                val data = dataSnapshot.getValue(AccountRelatedData::class.java)
                log.info("In onDataChange method")
                println(data)
            }

            @Override
            override fun onCancelled(databaseError: DatabaseError) {
                log.info("In onCancelled method")
                println("The read failed: " + databaseError.code)
            }
        }

        accountRelatedDataRef.addValueEventListener(listener)
    }

    companion object {
        private val log = LoggerFactory.getLogger(AccountRelatedDataService::class.java)
        private const val refPath = "accountRelatedData"
    }

在同一个数据库对象上插入数据可以正常工作。

请注意,数据库是通过构造函数中的 Spring 连接的。它是一个 Bean,定义为:

@Bean
    fun firebaseDatabase(): FirebaseDatabase {
        return FirebaseDatabase.getInstance()
            ?: throw java.lang.IllegalStateException("Firebase database not available")
    }

回应 Frank van Puffelen 的评论。对于insertRelatedData,我得到正常的日志,例如:

2021-09-02 20:58:21.619 DEBUG 4270 --- [database-worker] c.g.f.database.connection.Connection     : [conn_0] Sending data: {t=d, d={a=p, r=2, b={p=accountRelatedData/1563c2f2-d95e-47d5-b0a8-6a63db617f13, d={cryptoWallets={ETH={ticker=ETH, address=0x0234b8305a7a821277c0b09951e5a536af0c4d24, validFrom={nano=860000000, epochSecond=1630609099}}}, fireBaseUID=1563c2f2-d95e-47d5-b0a8-6a63db617f13}}}}
2021-09-02 20:58:21.619 DEBUG 4270 --- [database-worker] c.g.f.d.connection.WebsocketConnection   : [ws_0] Reset keepAlive. Remaining: 44998
2021-09-02 20:58:21.739 DEBUG 4270 --- [ebsocket-worker] c.g.f.d.connection.WebsocketConnection   : [ws_0] WS message: {"t":"d","d":{"r":2,"b":{"s":"ok","d":""}}}
2021-09-02 20:58:21.739 DEBUG 4270 --- [database-worker] c.g.f.d.connection.WebsocketConnection   : [ws_0] Reset keepAlive. Remaining: 44879
2021-09-02 20:58:21.739 DEBUG 4270 --- [database-worker] c.g.f.d.connection.WebsocketConnection   : [ws_0] Handle new frame count: 1
2021-09-02 20:58:21.739 DEBUG 4270 --- [database-worker] c.g.f.d.connection.WebsocketConnection   : [ws_0] Parsed complete frame: {t=d, d={r=2, b={s=ok, d=}}}
2021-09-02 20:58:21.739 DEBUG 4270 --- [database-worker] c.g.f.database.connection.Connection     : [conn_0] Received data message: {r=2, b={s=ok, d=}}
2021-09-02 20:58:21.739 DEBUG 4270 --- [database-worker] c.g.f.d.connection.PersistentConnection  : [pc_0] p response: {s=ok, d=}

对于getAccountRelatedData,我从 Firebase 客户端根本没有收到任何日志语句,尽管日志级别为 DEBUG。

【问题讨论】:

  • 你的 onDataChange 或 onCancelled 是否被调用过?
  • 不,这正是问题所在。至少在连接初始数据时应该调用它,但不是。
  • 在这种情况下,您确定用户的设备上有互联网连接吗?您的database 对象是如何定义的?您的数据库位置在哪里?
  • 这一切设置正确,因为 insertRelatedData 在同一个数据库上工作没有问题。让我把数据的打印屏幕放在帖子里。
  • 霍伊安德烈。为了清楚起见:您是说您的 accountRelatedDataRef.addValueEventListener(listener) 已执行,但随后既未调用 onDataChange 也未调用 onCancelled,而来自同一进程的写入成功?如果是这样,在您附加侦听器后不久,是否有任何来自数据库客户端的调试日志记录?

标签: kotlin firebase-realtime-database firebase-admin


【解决方案1】:

我想我知道我做错了什么。从 Firebase 读取时,它是异步的,因此添加了侦听器,但代码是非阻塞的,因此函数刚刚结束。数据库客户端甚至没有机会连接或监听事件。

我现在所做的如下,使用CompletableFuture 并等待onDataChange 回调完成。这样我可以等待结果,如果时间太长,让它超时。然后,我将使用此结果传回控制器,从而传回调用我们的 REST API 的客户端。

getRelatedData的改编代码:

fun getRelatedData() : AccountRelatedData? {
        var completableFuture = CompletableFuture<AccountRelatedData>()

        val listener = object : ValueEventListener {

            @Override
            override fun onDataChange(dataSnapshot: DataSnapshot) {
                val data = dataSnapshot.getValue(AccountRelatedData::class.java)
                log.info("In onDataChange method")
                println(data)
                completableFuture.complete(data)
            }

            @Override
            override fun onCancelled(databaseError: DatabaseError) {
                log.info("In onCancelled method")
                println("The read failed: " + databaseError.code)
            }
        }
        accountRelatedDataRef.addValueEventListener(listener)
        return completableFuture.get(10, TimeUnit.SECONDS)
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-01
    • 2018-12-05
    • 2020-11-03
    • 2021-11-03
    • 2019-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多