簡體   English   中英

如何從 Firestore 獲取數組?

[英]How to get an array from Firestore?

我將如下所示的數據結構存儲在 Cloud Firestore 中。 我想保存dungeon_group ,它是一個存儲在 Firestore 中的字符串數組。

我很難獲取數據並存儲為數組。 我只能得到一個奇怪的字符串,但是有什么方法可以存儲為字符串數組? 下面是我使用的代碼。

我能夠在 Swift 中實現這一點,如下所示,但不確定如何在 Android 中做到這一點。

在此處輸入圖片說明

迅速:

Firestore.firestore().collection("dungeon").document("room_en").getDocument { 
    (document, error) in
    if let document = document {
        let group_array = document["dungeon_group"] as? Array ?? [""]
        print(group_array)
    }    
}

Java安卓:

FirebaseFirestore.getInstance().collection("dungeon")
                 .document("room_en").get()
                 .addOnCompleteListener(new 
                     OnCompleteListener<DocumentSnapshot>() {
                     @Override
                     public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                         DocumentSnapshot document = task.getResult();
                         String group_string= document.getData().toString();
                         String[] group_array = ????
                         Log.d("myTag", group_string);
                     }
                 });

控制台輸出如下:

{dungeon_group=[3P,緊急,任務挑戰,降臨,協作,日常,技術,普通]}

當您調用DocumentSnapshot.getData() 時,它會返回一個 Map。 您只是在該地圖上調用 toString() ,這將為您提供文檔中所有數據的轉儲,這並不是特別有用。 您需要按名稱訪問dungeon_group字段:

DocumentSnapshot document = task.getResult();
List<String> group = (List<String>) document.get("dungeon_group");
  • 編輯:類型轉換中的語法錯誤

您的問題有兩種解決方案,一種是您可以通過以下方式從文檔中轉換值:

DocumentSnapshot document = task.getResult();
List<String> dungeonGroup = (List<String>) document.get("dungeon_group");

或者,我會向您推薦這個解決方案,因為在您開發應用程序時,您的模型總是有可能發生變化 此解決方案只是對 Firebase POJO 中的所有內容進行建模,即使它們只有一個參數:

public class Dungeon {

    @PropertyName("dungeon_group")
    private List<String> dungeonGroup;

    public Dungeon() {
        // Must have a public no-argument constructor
    }

    // Initialize all fields of a dungeon
    public Dungeon(List<String> dungeonGroup) {
        this.dungeonGroup = dungeonGroup;
    }

    @PropertyName("dungeon_group")
    public List<String> getDungeonGroup() {
        return dungeonGroup;
    }

    @PropertyName("dungeon_group")
    public void setDungeonGroup(List<String> dungeonGroup) {
        this.dungeonGroup = dungeonGroup;
    }
}

請記住,您可以使用 Annotation @PropertyName 來避免以與您在數據庫中的值相同的方式調用您的變量。 以這種方式最終做到這一點,您可以這樣做:

DocumentSnapshot document = task.getResult();
Dungeon dungeon= toObject(Dungeon.class);

希望它會幫助你! 快樂編碼!

如果你想獲得整個dungeon_group數組,你需要像這樣迭代Map

Map<String, Object> map = documentSnapshot.getData();
for (Map.Entry<String, Object> entry : map.entrySet()) {
    if (entry.getKey().equals("dungeon_group")) {
        Log.d("TAG", entry.getValue().toString());
    }
}

但請注意,即使dungeon_group對象作為數組存儲在數據庫中, entry.getValue()返回一個ArrayList不是數組。

如果您考慮這種替代數據庫結構,對您來說更好的方法是,其中每個group都是Map的鍵,並且所有值都設置為布爾值true

dungeon_group: {
    3P: true,
    Urgent: true,
    Mission Chalange: true
    //and so on
}

使用此結構,您還可以根據dungeon_group地圖中存在的屬性查詢它,否則如官方文檔中所示

雖然 Cloud Firestore 可以存儲數組, it does not support查詢數組成員或更新單個數組元素。

2021 年 1 月 13 日編輯:

如果您有一個對象數組而不是字符串值數組,那么您可以將該對象數組映射到自定義對象列表,如以下文章中所述:

2018 年 8 月 13 日編輯:

根據有關數組成員資格的更新文檔,現在可以使用whereArrayContains()方法基於數​​組值過濾數據。 一個簡單的例子是:

CollectionReference citiesRef = db.collection("cities");
citiesRef.whereArrayContains("regions", "west_coast");

此查詢返回每個城市文檔,其中區域字段是包含 west_coast 的數組。 如果數組具有您查詢的值的多個實例,則該文檔僅包含在結果中一次。

由於您的文檔看起來像這樣"dongeon_group=[SP, urgent, missinon challenge,...]當您將其轉換為字符串時,例如通過String.valueOf(document.getData())

我認為另一種簡單地實現這一點的方法是將文檔立即解壓縮為一串數組,如下所示:

String[] unpackedDoc = document.getData().entrySet().toArray()[0].toString().split("=")[1].split(",");

解釋

document是從documentSnapshot.getDocuments() ,它返回一個包含您的文檔的列表。

由於您的來自 firestore 的文檔似乎是嵌套的,因此調用document.getData()將返回您的文檔的列表,當然是一個包含單個元素的列表。 document.getData().entrySet()將使文檔准備好被轉換為數組(你不能單獨使用 getData() 這樣做)也包含單個元素。 訪問單個元素document.getData().entrySet().toArray()[0]然后將其轉換為字符串, document.getData().entrySet().toArray()[0].toString()將離開然后可以拆分的字符串(使用字符串中的= ),然后取出第二部分。 第二部分也可以拆分為包含文檔值的數組。

由於此解決方案一次轉換一個元素,您可以將其包裝在一個循環中,以便您可以轉換所有可用的文檔。

例如:

for(DocumentSnapshot document :documentSnapshot.getDocuments()){ String[] unpackedDoc = document.getData().entrySet().toArray()[0].toString().split("=")[1].split(","); //do something with the unpacked doc

}

我如何在我的生產應用程序中存檔。

全球申報

private final FirebaseFirestore FIRE_STORE_DB;

參考

this.FIRE_STORE_DB = FirebaseFirestore.getInstance();

征收方式

 public CollectionReference getCOLLECTION_REF() {
    return FIRE_STORE_DB.collection(Global.COLLECTION_USER);
}

如果等於返回false,我的recuirment是獲取數組的最后一個索引時間到當前時間。

public void dailyCheck(String UID, OnCheckIn onCheckIn) {
    getCOLLECTION_REF().document(UID).get().addOnSuccessListener(documentSnapshot -> {
        if (documentSnapshot.exists()) {
            List< String > dateList = (List< String >) documentSnapshot.get(FIELD_DAILY_CHECK_IN);
            if (dateList != null) {
                String lastDate = dateList.get(dateList.size() - 1);
                if (!lastDate.equals(getCurrentTimeStamp())) {
                    onCheckIn.todayCheckIn(false);
                } else {
                    Log.e(TAG, "LAST DATE EQUAL ---------------> RETURN");
                    onCheckIn.todayCheckIn(true);
                }
            } else {
                Log.e(TAG, "DATE LIST ---------------> NULL RETURN");
            }

        } else {
            Log.e(TAG, "LOGIN DATE NOT EXIST ---------------> checkInDate");
        }
    });
}

我如何在我的活動中獲得它

public interface OnCheckIn {
    void todayCheckIn(boolean check);
}

下面 - 我怎么稱呼它

dbHelper.dailyCheck(CURRENT_USER, check -> {
        if (!check) {
            // todo
        } else {
            // 
        }
    });

注釋 - 這個 dbHelper 是一個類名->如果你對這個答案有任何疑問,請在下面評論

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM