dev*_*747 5 java firebase-realtime-database firebase-admin
我正在为Java使用Firebase管理员SDK。当我创建一个Java控制台应用程序时,下面的代码可以按预期工作。但是,如果我在springboot应用程序中的Bean初始化中放入相同的代码,则它永远不会进入onDataChange EventHandler内部。
我什至尝试在结尾放置足够延迟的Thread.sleep(),以检查是否正在发生这种情况,因为初始化bean的线程正在退出。但是,这没有帮助。
在spring bean中执行此操作的正确方法是什么?
import com.google.auth.oauth2.GoogleCredentials;
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOptions;
import com.google.firebase.database.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Repository;
import java.io.File;
import java.io.FileInputStream;
import java.util.HashMap;
import java.util.Map;
@Repository
@EnableAsync
public class MyBean {
FirebaseDatabase db;
public MyBean() {
try {
File file = new File(
getClass().getClassLoader().getResource("myKey.json").getFile()
);
FileInputStream fis = new FileInputStream(file);
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredentials(GoogleCredentials.fromStream(fis))
.setDatabaseUrl("https://myUrl/")
.build();
FirebaseApp.initializeApp(options);
db = FirebaseDatabase.getInstance();
DatabaseReference ref = db
.getReference("/a/b/c");
ref.addValueEventListener(new ValueEventListener() {
//The code execution never comes in here
public void onDataChange(DataSnapshot dataSnapshot) {
System.out.println("dataSnapshot.exists() :"+ dataSnapshot.exists());
}
public void onCancelled(DatabaseError error) {
System.out.print("Error: " + error.getMessage());
}
});
// Thread.sleep(10000);
} catch (Exception ex) {
String err=ex.getMessage();
}
}
`
Run Code Online (Sandbox Code Playgroud)
Geo*_*rge -1
看一下该方法的源码FirebaseReference.getReference():
public DatabaseReference getReference() {
return new DatabaseReference(ensureRepo(), Path.getEmptyPath());
}
Run Code Online (Sandbox Code Playgroud)
DatabaseReference每次你调用它时它都会创建一个新的。您现在执行此操作的方式是将 a 添加ValueEventListener到 a 中DatabaseReference,该 a 只会被垃圾收集,因为您没有以某种方式将其传递出此方法。
我建议将您的DatabaseReference对象声明为类中的 bean @Configuration:
@Configuration
public class FirebaseConfig {
// This is just the ApplicationContext, injected through abstraction
private final ResourceLoader resourceLoader;
@Autowired // Constructor injection, recommended above field and setter injections
public FirebaseConfig(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
@Bean
public FirebaseDatabase firebaseDatabase() throws IOException {
Resource resource = resourceLoader.getResource("classpath:myKey.json");
InputStream inputStream = resource.getInputStream();
FirebaseOptions firebaseOptions = new FirebaseOptions.Builder()
.setCredentials(GoogleCredentials.fromStream(inputStream))
.setDatabaseUrl("url")
.build();
FirebaseApp.initializeApp(firebaseOptions);
return FirebaseDatabase.getInstance();
}
@Bean
public DatabaseReference databaseReference(FirebaseDatabase firebaseDatabase) {
DatabaseReference ref = firebaseDatabase.getReference();
ref.addValueEventListener(new ValueEventListener() {
public void onDataChange(DataSnapshot dataSnapshot) {
System.out.println("dataSnapshot.exists() :" + dataSnapshot.exists());
}
public void onCancelled(DatabaseError error) {
System.out.print("Error: " + error.getMessage());
}
});
return ref;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,在整个 Spring 应用程序中,您应该自动装配这个 DatabaseReference bean。
一个更优雅的解决方案是将其分离ValueEventListener到它自己的 bean 中,并将其自动装配到DatabaseReferencebean 方法中:
@Bean
public DatabaseReference databaseReference(
FirebaseDatabase firebaseDatabase,
// List injection will be populated with all ValueEventListener beans in the ApplicationContext
List<ValueEventListener> valueEventListeners
) {
DatabaseReference ref = firebaseDatabase.getReference();
valueEventListeners.forEach(ref::addValueEventListener);
return ref;
}
Run Code Online (Sandbox Code Playgroud)
在一个单独的类中:
@Component
public class SystemOutListener implements ValueEventListener {
@Override
public void onDataChange(DataSnapshot snapshot) {
System.out.println("dataSnapshot.exists() :"+ snapshot.exists());
}
@Override
public void onCancelled(DatabaseError error) {
System.out.print("Error: " + error.getMessage());
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
80 次 |
| 最近记录: |