我在 Studio 中遇到了 firebase 查詢問題。我正在嘗試抽象一個簡單的查詢以獲取存盤在集合中的物件串列(在我的情況下為“用戶”)我想創建一個存盤在類中的函式,該函式可以被專案中的每個片段呼叫。但是我沒有找到任何方法可以做到這一點,重復相同的指令是唯一的方法嗎?這是一個例子
db.collection("users") //get all the users
.get()
.addOnCompleteListener(task -> {
if (task.isSuccessful()) {
if(task.getResult() != null) {
for (QueryDocumentSnapshot document : task.getResult()) {
usersList.add(document.toObject(User.class));
} else {
Log.w(LOGIN, "Error getting documents.", task.getException());
}
});
每次需要時我都會撰寫這些代碼行,但我想創建一個回傳 List 的方法,如下例所示:
public static List<User> getUsers(FirebaseFirestore db) {
List<User> usersList = new ArrayList<>();
db.collection("users") //get all the users
.get()
.addOnCompleteListener(task -> {
if (task.isSuccessful()) {
if(task.getResult() != null) {
for (QueryDocumentSnapshot document : task.getResult()) {
usersList.add(document.toObject(User.class));
} else {
Log.w(LOGIN, "Error getting documents.", task.getException());
}
});
} else {
//error
}
return usersList;
}
uj5u.com熱心網友回復:
資料從 Firestore(和大多數現代云 API)異步加載,因為這可能需要一些時間。主代碼不會在這段時間內阻塞應用程式,而是繼續執行。然后當資料可用時,您的addOnCompleteListener回呼將使用該資料執行。
看到這一點的最簡單方法是在代碼中添加一些適當的日志記錄:
public static List<User> getUsers(FirebaseFirestore db) {
Log.i(LOGIN, "Starting getUsers");
db.collection("users") //get all the users
.get()
.addOnCompleteListener(task -> {
Log.i(LOGIN, "Got data");
})
Log.i(LOGIN, "Returning from getUsers");
}
運行此代碼時,您將獲得以下輸出:
啟動 getUsers
從 getUsers 回傳
得到資料
這可能不是您期望的順序,但它完全解釋了為什么呼叫的代碼getUsers永遠不會看到資料:當您return usersList運行時,資料尚未加載并且usersList.add(document.toObject(User.class))從未被呼叫。
解決方案總是一樣的:任何需要資料庫資料的代碼,要么在完成回呼中,要么從那里呼叫,要么通過其他方式同步。
一個簡單的例子是創建一個自定義回呼函式:
public interface GetUsersCallback {
void onCallback(List<User> users);
}
然后將其傳遞給getUsers,它可以在從資料庫中獲取并處理結果后呼叫它:
public static void getUsers(FirebaseFirestore db, GetUsersCallback callback) {
// ??
List<User> usersList = new ArrayList<>();
db.collection("users") //get all the users
.get()
.addOnCompleteListener(task -> {
if (task.isSuccessful()) {
if(task.getResult() != null) {
for (QueryDocumentSnapshot document : task.getResult()) {
usersList.add(document.toObject(User.class));
} else {
Log.w(LOGIN, "Error getting documents.", task.getException());
}
});
callback(usersList); // ??
}
}
然后你可以像這樣使用它:
getUsers(new GetUsersCallback() {
@Override
public void onCallback(List<User> users) {
Log.i(LOGIN, "Found " users.size() " users");
}
});
在處理云 API 時,資料的異步加載非常普遍,但當您第一次遇到它時,它也相當令人困惑。我建議閱讀其中一些答案以了解更多資訊:
- 如何檢查某個資料是否已經存在于firestore中
- 如何作為方法的結果回傳 DocumentSnapShot?
- 為什么呼叫 API 的函式回傳空值或 null 值?
- Firebase Firestore 從集合中獲取資料
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/430096.html
