我正在为我正在处理的Firebase数据库中的“graylist”中的条目编写一个静态方法,并检查用户输入以查看是否该条目存在。我能够很好地找到条目,但由于线程在从Firebase读取/写入数据时的工作方式存在一些限制,因此我无法弄清楚如何通知用户操作是否成功或不。通知用户Firebase搜索是否成功
我有以下方法:
public static void addUser() {
final boolean [] complete = new boolean[1];
final String email = Tools.getEmail();
DatabaseReference grayRef = FirebaseDatabase.getInstance().getReference().child("graylist");
// Search the graylist for the email specified.
CountDownLatch latch = new CountDownLatch(1); // need this so Parse-Ly doesn't close before event fires
grayRef.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onCancelled(DatabaseError dbe) {}
@Override
public void onDataChange(DataSnapshot snap) {
Iterable<DataSnapshot> graylist = snap.getChildren();
for(DataSnapshot gray : graylist) {
String uid = gray.getKey();
String em = gray.getValue(String.class);
if(em.equals(email)) {
// We found the one we're looking for. Insert its UID into the whitelist.
DatabaseReference whiteRef = FirebaseDatabase.getInstance().getReference().child("whitelist");
whiteRef.child(uid).setValue(email, new DatabaseReference.CompletionListener() {
@Override
public void onComplete(DatabaseError dbe, DatabaseReference dbr) {
complete[0] = true;
latch.countDown();
if(dbe != null) {
System.err.println("Error adding user to whitelist!");
dbe.toException().printStackTrace();
}
}
});
break;
}
}
if(latch.getCount() > 0) {
complete[0] = false;
latch.countDown();
}
}
});
try {
latch.await(); // wait for event to fire before we move on
} catch(InterruptedException ie) {
System.err.println("ERROR: Add user latch interrupted!");
ie.printStackTrace();
}
if(complete[0]) ParselyMain.createAlert(AlertType.CONFIRMATION, "User Added", "User added to the whitelist!");
else ParselyMain.createAlert(AlertType.INFORMATION, "User Not Found", "That user was not found in the graylist!");
}
我知道最后的布尔数组如何哈克是,但即使这是不是为我工作。这个想法是使用CountDownLatch,并且只在写入成功时才倒计数。如果读取了该列表中的所有条目并且CountDownLatch仍然为1,则没有任何内容被写入,并且它应该倒数退出该线程,但布尔值将确定该操作是否成功。
问题在于,它在调用onComplete方法之前似乎到达了for循环之后的if块,导致它认为操作失败(即使Firebase上的数据库显示其他情况),并输出了错误的警报。
任何人都可以想到一个更好的方法来处理这个问题,以便我可以正确告知他们,如果用户被添加到白名单或者如果用户没有找到?
不可能,因为onComplete在单独的线程上,JavaFX不允许你在主线程之外创建对话消息。这很令人沮丧。 –
这篇文章的帮助:http://stackoverflow.com/questions/19755031/how-javafx-application-thread-works? AFAIK Firebase会在主线程上触发'onComplete'回调,因此您需要在JavaFX线程上调用UI。 – manouti
顺便说一句你确定在另一个线程上调用了'onComplete'吗?在Android中,它在主线程上被调用,也许在JVM上它是相同的。在所有情况下,您都可以尝试链接帖子中的机制('Platform.runLater')。 – manouti