Firebase事务永远不会调用onComplete()

时间:2015-02-12 20:34:43

标签: java transactions firebase

在Java中使用Firebase,我的情况似乎从未调用Transaction.Handler.onComplete()

我试图等待特定事务的完成,所以我让调用线程继续前进,直到调用onComplete()。这是由现有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()肯定至少完成一次 - 我可以在网络界面中看到数据更新 - 但onComplete()永远不会被调用,我们只是挂起。

我无法看到此包装模式有任何问题:我在另一个Firebase上的测试main()方法中单独运行相同的事务,并且onComplete() 打来电话。

导致此挂起的原因是什么? Firebase的配置(例如auth?规则?)是否存在一些在此引入错误的内容?

修改

我没有包装图案时遇到同样的问题。这是代码:

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");

导致打印doing transaction并且Firebase中的数据发生了变化(我通过网络用户界面看到),但打印transaction finished。它只是挂起。

1 个答案:

答案 0 :(得分:4)

在Android上,所有Firebase回调都在主线程上运行。如果在主线程上调用latch.await()onComplete将永远无法运行,因为主线程被阻塞,导致死锁。