英文:
How to make spring controller json response wait until firebase query ends?
问题
I'm using an ajax call to spring controller to start a firebase query, save the result to the local database and return items saved in the local database (including the results saved from the current and previous firebase queries too). The problem is that since the firebase query runs async, the results from the local database query are returned before the firebase query finishes.
@PostMapping("/firebase-download")
@ResponseBody
public List<FirebaseTransactionRecord> firebaseDownload() {
firebaseService.downloadAndSaveFirebaseTransactions();
// wait for the query to end
return firebaseTransactionRecordRepository.findBySentFalse();
}
@Override
@Transactional
public void downloadAndSaveFirebaseTransactions() {
final List<FirebaseTransactionRecord> firebaseTransactions = new ArrayList<>();
firebaseDb.child(StringValueConstant.DB_CHILD_TEMPORARY_TRANSACTIONS)
.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot userSnapshot : snapshot.getChildren()) {
userSnapshot.getChildren().forEach(transactionSnapshot -> {
FirebaseTransactionRecord record = firebaseTransactionMapper
.toFirebaseTransactionRecord(transactionSnapshot);
firebaseTransactions.add(record);
});
}
saveFirebaseTransactionRecords(firebaseTransactions);
}
@Override
public void onCancelled(DatabaseError error) {
log.error("Error reading Firebase data:", error);
}
});
}
@Override
@Transactional
public void saveFirebaseTransactionRecords(List<FirebaseTransactionRecord> firebaseTransactions) {
firebaseTransactions.forEach(firebaseTransaction -> {
if (!firebaseTransactionRecordRepository.existsByReferralNumber(firebaseTransaction.getReferralNumber())) {
firebaseTransactionRecordRepository.save(firebaseTransaction);
}
});
}
英文:
I'm using an ajax call to spring controller to start a firebase query, save the result to local database and return items saved in the local database (including the results saved from the current and previous firebase queries too). The problem is that since the firebase query runs async, the results from the local database query are returned before the firebase query finishes.
How can I make the returned local database query wait until the firebase query finished?
@PostMapping("/firebase-download")
@ResponseBody
public List<FirebaseTransactionRecord> firebaseDownload() {
firebaseService.downloadAndSaveFirebaseTransactions();
// wait for the query to end
return firebaseTransactionRecordRepository.findBySentFalse();
}
@Override
@Transactional
public void downloadAndSaveFirebaseTransactions() {
final List<FirebaseTransactionRecord> firebaseTransactions = new ArrayList<>();
firebaseDb.child(StringValueConstant.DB_CHILD_TEMPORARY_TRANSACTIONS)
.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot userSnapshot : snapshot.getChildren()) {
userSnapshot.getChildren().forEach(transactionSnapshot -> {
FirebaseTransactionRecord record = firebaseTransactionMapper
.toFirebaseTransactionRecord(transactionSnapshot);
firebaseTransactions.add(record);
});
}
saveFirebaseTransactionRecords(firebaseTransactions);
}
@Override
public void onCancelled(DatabaseError error) {
log.error("Error reading Firebase data:", error);
}
});
}
@Override
@Transactional
public void saveFirebaseTransactionRecords(List<FirebaseTransactionRecord> firebaseTransactions) {
firebaseTransactions.forEach(firebaseTransaction -> {
if (!firebaseTransactionRecordRepository.existsByReferralNumber(firebaseTransaction.getReferralNumber())) {
firebaseTransactionRecordRepository.save(firebaseTransaction);
}
});
}
答案1
得分: 1
使用 CountdownLatch
应该可以解决问题。
将初始的门闩计数器设置为1(用于主监听器),然后在 onDataChange
中将其设置为子节点的数量。接下来将门闩传递给 saveFirebaseTransactionRecords
,并在每个事务完成时减少计数。一旦门闩计数达到0,就可以退出 downloadAndSaveFirebaseTransactions
。
英文:
Something with a CountdownLatch
should do the trick.
Set the initial latch counter to 1 (for the main listener), then set it to the number of child nodes in onDataChange
. Next pass the latch to saveFirebaseTransactionRecords
and decrease it when each transaction completes. Once the latch reaches 0, you can exit out of downloadAndSaveFirebaseTransactions
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论