Посмотрите на исходный код метода FirebaseReference.getReference()
:
public DatabaseReference getReference() {
return new DatabaseReference(ensureRepo(), Path.getEmptyPath());
}
Он создает новый DatabaseReference
каждый раз, когда вы вызываете его. То, как вы делаете это прямо сейчас, - вы добавляете ValueEventListener
к DatabaseReference
, который просто собирает мусор, поскольку вы каким-то образом не пропускаете его из этого метода.
Я предлагаю объявитьВаш DatabaseReference
объект в виде компонента в классе @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;
}
}
Теперь во всем приложении Spring необходимо автоматически подключать этот компонент DatabaseReference.
Еще более элегантным решением было быразделить ValueEventListener
на его собственный компонент и автоматически связать его с методом DatabaseReference
:
@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;
}
И в отдельном классе:
@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());
}
}