【问题标题】:Java, get Keys from Map that has data from FireStoreJava,从具有 FireStore 数据的 Map 获取密钥
【发布时间】:2021-11-12 01:15:11
【问题描述】:

我正在从 FireStore 获取数据到地图中,我在 Firestore 中的数据如下所示:

(Auto-Document ID)
    title="title1"
    body="body1"
(Auto-Document ID)
    title="title2"
    body="body2"

当我将它们加载到地图中时,它看起来像这样:

loadNoteCallBack: {rsmw3EkfIjUQxrzRiyy7={body=body2, title=title2}, sTEfYCcPK9lw77xWS8H5={body=body1, title=title1}}

“rsmw3EkfIjUQxrzRiyy7”和“sTEfYCcPK9lw77xWS8H5”是自动生成的文档ID-s

现在我的问题是,我想从中提取标题,但我不知道如何操作。
我试过这个:

List<String> keys = new ArrayList<>();

for (String key : data.keySet()) {
    keys.add(key);
}

但我以这种方式取回了文档 ID-s。

标题:[rsmw3EkfIjUQxrzRiyy7, sTEfYCcPK9lw77xWS8H5]

我应该如何获得标题?

更新

我想我做到了。是不是很好解决这个问题?

    public static void loadNote() {
    db.collection("Datas")
            .get()
            .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                @Override
                public void onComplete(@NonNull Task<QuerySnapshot> task) {
                    if (task.isSuccessful()) {
                        Map<String, Object> data = new HashMap<>();
                        List<String> titles = new ArrayList<>();
                        for (QueryDocumentSnapshot document : task.getResult()) {
                            titles.add(document.getString("title"));
                            data.put(document.getId(),document.getData());
                        }                            
                        defaultEntitys.loadNoteCb(data,titles);
                    } else {
                        Log.d(TAG, "Error getting documents: ", task.getException());
                    }
                }
            });

【问题讨论】:

  • rsmw3EkfIjUQxrzRiyy7 & sTEfYCcPK9lw77xWS8H5 会成为你地图的关键吗? & title, body 将是对象的一部分,可以用作 value 是你想要做的吗?
  • 是的,我只想得到所有的标题
  • 您正确获取了自动生成的密钥。你想要得到的是价值的一部分,而不是关键。
  • @IslamEl-Rougy 我明白了,那我应该如何从值中获取标题?

标签: java google-cloud-firestore


【解决方案1】:

更新

选项 1:

如果直接使用 Firestore 查询引用,请使用 QueryDocumentSnapshot 类方法从 Firestore 文档中获取值

进口

import com.google.cloud.firestore.FirestoreOptions;
import com.google.cloud.firestore.QueryDocumentSnapshot;
import com.google.cloud.firestore.QuerySnapshot;

代码

  Firestore db = firestoreOptions.getService();
  ApiFuture<QuerySnapshot> query = db.collection("data").get();
  QuerySnapshot querySnapshot = query.get();
  List<QueryDocumentSnapshot> documents = querySnapshot.getDocuments();
  ArrayList<String> titles = new ArrayList<>();
  for (QueryDocumentSnapshot document : documents) {
    System.out.println("auto id: " + document.getId());
    String title = document.getString("title");
    titles.add(title);
  }
  System.out.println("titles = " + titles);

选项 2:

使用data.entrySet() 获取键值对,如下所示

for (Map.Entry<String, Object> o : data.entrySet()) {
    String key = o.getKey();
    Object value = o.getValue();
}

使用任何 JSON 库(如 Jackson)将值解析为 JSON 对象或类对象以获取标题。

【讨论】:

    【解决方案2】:

    使用 Java8 流的更简洁的方法是:

    Map<String,FireStore> map=new HashMap<>();
    
    FireStore f1=new FireStore("title1","body1");
    FireStore f2=new FireStore("title2","body2");
    
    map.put("rsmw3EkfIjUQxrzRiyy7",f1);
    map.put("sTEfYCcPK9lw77xWS8H5",f2);
    
    List<String> titles = map.entrySet()
            .stream()
            .map(e -> e.getValue())
            .map(FireStore::getTitle)
            .collect(Collectors.toList());
    
    System.out.println(titles);
    

    您的 FireStore 对象:

    public class FireStore {
        private String body;
        private String title;
        public FireStore(String title,String body) {
            this.body = body;
            this.title = title;
        }
        public String getBody() { return body; }
        public void setBody(String body) { this.body = body; }
        public String getTitle() { return title; }
        public void setTitle(String title) { this.title = title; }
    }
    

    作为您从link 提供的信息。您需要添加以下更改。

    //asynchronously retrieve all documents
    ApiFuture<QuerySnapshot> future = db.collection("cities").get();
    // future.get() blocks on response
    List<QueryDocumentSnapshot> documents = future.get().getDocuments();
    List<String> titles=new ArrayList<>();
    for (QueryDocumentSnapshot document : documents) {
      titles.add(document.get("title")); //this will get titles and add into titles list.
    }
    

    【讨论】:

    • 如果我没有 ForeStore 对象怎么办?在我们的项目中,用户可以在数据库中放入任何内容,但必须有一个命名的标题
    • 所以你的值将是一个有效的 json ?或者它只是一个逗号分隔的字符串值,它总是有 title
    • 一个有效的 JSON。 FireStore 将我放在那里的数据存储为 json,对吗?
    • 你能发布你从 FireStore 获得的 json 吗?
    【解决方案3】:

    Firebase 版本 9(网络/JS) 要从 Firestore 文档集合中获取文档键(字段):

     // import from firebase (including the db ref!)
        import { collection, query, getDocs, doc } from "firebase/firestore";
        // set up query - collection name can be passed as variable
        const q = query(collection(db, 'posts'), limit(1));
        const docKeys
     // You need to use async/await when calling on Firestore
        const getDocKeys = async () => {
          const querySnapshot = await getDocs(q);
          querySnapshot.forEach((doc) => {
            docKeys = Object.keys(doc.data());
            console.log(docKeys);
     // You can go further & push result to array and sort if needed...
          });
        };
    
    // run function...
        getDocKeys();
    

    【讨论】:

    • 进行编辑是为了更正在 Vue 3/Quasar 上下文中使用的原始代码 - docKeys 变量被定义为 ref - const docKeys = ref(null) 并因此使用了赋值.value - 写成:docKeys.value = Object.keys(doc.data())
    猜你喜欢
    • 2019-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多