我正在等待某个特定事务完成,所以我一直保持调用线程前进,直到调用 onComplete()。这是通过在现有的Transaction.Handler txn 周围的一个匿名装饰器完成的。
Transaction.Handler txn = ... CountDownLatch latch = new CountDownLatch(1); ref.runTransaction(new Transaction.Handler(){ $ b @Override public Transaction.Result doTransaction(MutableData data){ return txn。 doTransaction(data); } @Override public void onComplete(FirebaseError e,boolean wasCommitted,DataSnapshot data){ System.out.println(never ); txn.onComplete(e,wasCommitted,data); if(e!= null ||!wasCommitted){ System.out.println(error:+ e +,承诺:+ wasCommitted); } latch.countDown(); } }); latch.await(); System.out.println(never printed);doTransaction()至少完成一次 - 我可以看到Web界面中的数据更新 - 但是 onComplete()永远不会被调用,我们只是挂起。
我看不到这个包装器模式有什么问题:我在一个不同的Firebase上测试 main()方法中单独运行相同的事务,而 onComplete() 被调用。是什么原因造成这个挂起?有没有关于Firebase的配置(例如auth?rules?)的问题?
编辑
没有包装模式,我遇到了同样的问题。代码如下: $ p $ CountDownLatch latch = new CountDownLatch(1); ref.runTransaction(new Transaction.Handler(){ $ b @Override public void onComplete(FirebaseError e,boolean b,DataSnapshot data){ if(e != null ||!b){ System.out.println(error:+ e +,committed:+ b); } System.out.println( ); latch.countDown(); } @Override public Result doTransaction(MutableData data){ System。 out.println(doing transaction); data.child(...)。setValue(...); return Transaction.success(data); } }); latch.await(); System.out.println(never printed);
结果打印做交易 Firebase中的数据更改(通过Web UI查看),但不打印完成的事务。它只是挂起。
解决方案在Android上,所有Firebase回调都在主线程上运行。如果在主线程中调用 latch.await(), onComplete 永远不会有机会运行,因为主线程被阻塞,导致死锁。
Working with Firebase in Java, I have a situation where it seems my Transaction.Handler.onComplete() is never called.
I'm trying to wait for completion on a particular transaction, so I keep the calling thread from advancing until onComplete() is called. This is done by an anonymous decorator around the existing Transaction.Handler txn.
Transaction.Handler txn = ... CountDownLatch latch = new CountDownLatch(1); ref.runTransaction(new Transaction.Handler() { @Override public Transaction.Result doTransaction(MutableData data) { return txn.doTransaction(data); } @Override public void onComplete(FirebaseError e, boolean wasCommitted, DataSnapshot data) { System.out.println("never printed"); txn.onComplete(e, wasCommitted, data); if(e != null || !wasCommitted) { System.out.println("error: " + e + ", committed: " + wasCommitted); } latch.countDown(); } }); latch.await(); System.out.println("never printed");doTransaction() definitely completes at least once - and I can see the data update in the web interface - but onComplete() is never called and we just hang.
I can't see anything wrong with this wrapper pattern: I ran the same transaction alone in a test main() method on a different Firebase, and onComplete() was called.
What is causing this hang? Is there something about a Firebase's configuration (e.g. auth? rules? ) that's introducing a bug here?
EDIT
I'm having the same problem without the wrapper pattern. Here's that code:
CountDownLatch latch = new CountDownLatch(1); ref.runTransaction(new Transaction.Handler() { @Override public void onComplete(FirebaseError e, boolean b, DataSnapshot data) { if(e != null || !b) { System.out.println("error: " + e + ", committed: " + b); } System.out.println("transaction finished!"); latch.countDown(); } @Override public Result doTransaction(MutableData data) { System.out.println("doing transaction"); data.child(...).setValue(...); return Transaction.success(data); } }); latch.await(); System.out.println("never printed");Which results in printing doing transaction and the data changing in the Firebase (which I see via web UI), but not printing transaction finished. It just hangs.
解决方案On Android all Firebase callbacks are run on the main thread. If you call latch.await() on the main thread, onComplete will never have the chance to run, because the main thread is blocked, resulting in a deadlock.
更多推荐
Firebase交易永远不会调用onComplete()
发布评论