我遇到了下面这段代码的问题,该代码几乎逐字地从Firebase SDK Java文档中复制到了工作中。我是一个真正的语言的新手,比如来自PHP和JavaScript的webdev背景的Java。
基本上没有触发addListenerForSingleValueEvent来返回数据。我注意到了这一点,因为系统打印输出没有触发,因此我认为监听事件没有触发。
我怀疑这与我有限的知识如何与函数本身的工作方式有关,就像我缺少一些关于类和函数如何相互作用的结构知识。
任何帮助将不胜感激,谢谢。
class FireBase {
public static void main(String[] args) throws IOException {
// Fetch the service account key JSON file contents
FileInputStream serviceAccount = new FileInputStream("key.json");
// Initialize the app with a service account, granting admin privileges
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredential(FirebaseCredentials.fromCertificate(serviceAccount))
.setDatabaseUrl("https://ssworks-adwords.firebaseio.com/")
.build();
FirebaseApp.initializeApp(options);
// As an admin, the app has access to read and write all data, regardless of Security Rules
DatabaseReference ref = FirebaseDatabase
.getInstance()
.getReference("petitions");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
System.out.println("Before Get Value");
Object document = dataSnapshot.getValue();
System.out.println(document);
}
@Override
public void onCancelled(DatabaseError arg0) {
// TODO Auto-generated method stub
System.out.println("This didn't work");
}
});
}
}
答案 0 :(得分:5)
如果你有一个通过某个类的main函数在命令行上调用的java程序,你必须在数据库监听器触发之前阻止该main函数返回。否则,程序将立即终止,并且听众永远不会开火。重要的是要记住所有Firebase侦听器都是异步的,Firebase管理自己的守护程序线程以与服务器通信。
对于使一个简单的程序等到侦听器触发的情况,你可以使用这种模式来阻止主线程等待监听器:
CountDownLatch latch = new CountDownLatch(1);
ref.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
System.out.println("onDataChange: " + dataSnapshot);
latch.countDown();
}
@Override
public void onCancelled(DatabaseError databaseError) {
System.out.println("onCanceled: " + databaseError);
latch.countDown();
}
});
latch.await();
使用CountDownLatch不是您唯一的选择。你可以做任何你想做的事情,以确保过程不会停止,包括简单地睡觉主线程的时间超过听众发射的时间。