【问题标题】:Is there a way to get document ID of item from FirestoreRecyclerAdapter?有没有办法从 FirestoreRecyclerAdapter 获取项目的文档 ID?
【发布时间】:2018-04-07 14:06:03
【问题描述】:

我可以手动查询 Firestore 并获取 ID,但我使用的是 FirestoreRecyclerAdapter,因为它附带了大量开箱即用的额外工作。所以,如果我有这样的代码:

FirebaseFirestore db = FirebaseFirestore.getInstance();

Query query = db.collection(COLLECTION_NAME)
        .whereEqualTo("userId", USER_ID)
        .limit(LIMIT);

FirestoreRecyclerOptions options = new FirestoreRecyclerOptions
        .Builder<SomeEntity>()
        .setQuery(query, SomeEntity.class)
        .build();

FirestoreRecyclerAdapter adapter = new FirestoreRecyclerAdapter<SomeEntity, MyHolder>(options) {
    @Override
    public void onBindViewHolder(MyHolder holder, int position, SomeEntity model) {
        // I need model ID here
    }
}

所以,如果我使用FirestoreRecyclerAdapter,它会自动将我的SomeEntity 类反序列化为model 对象。这一切都很好,但现在我需要将侦听器附加到列表中,并对模型 ID 做出反应。现在,如果我从 Firestore 手动反序列化对象,我会这样做:

for (DocumentSnapshot document : task.getResult()) {
    SomeEntity entity = document.toObject(SomeEntity.class).setId(document.getId());
    list.add(entity);
}

但是,由于 FirestoreRecyclerAdapter 正在为我进行反序列化,所以我不能自己致电 document.getId()。当我使用onBindViewHolder 方法时,我不再有权访问文档 ID。是否有一些我遗漏的方法,一些从我忽略的适配器中检索 ID 的方法?

注意,我不认为将 ID 作为字段冗余存储是一种解决方案。我宁愿继承和覆盖FirestoreRecyclerAdapter,但如果我能在没有那么多工作的情况下解决这个问题,我更愿意。

【问题讨论】:

  • 这有点傻,但我在阅读 this comment. 后将文档 ID 作为字段保存在文档本身中

标签: android firebase google-cloud-firestore firebaseui


【解决方案1】:

当您需要文档 ID 时,您应该已经知道有关您正在处理的项目的一些信息。通常这将是项目在列表中的位置。 IE。当用户单击一个项目时,单击处理程序将传递该项目的 ID。如果你有position,你可以从适配器获得DataSnapshot

adapter.getSnapshots().getSnapshot(position);

因此,如果您想获得 ID,您可以通过以下方式获得:

String id = adapter.getSnapshots().getSnapshot(position).getId();

【讨论】:

  • 谢谢,这是拼图中缺失的部分。我讨厌整个 NoSql 命名约定,我从来没有想过在方法中寻找“快照”。
  • 说实话,我对此也感到有些惊讶。在实时数据库适配器中,它只是adapter.getRef(position).getKey()
  • 关于定价,以这种方式获取 ID 是否算作一个文档读取?谢谢
  • 是的,读取ID需要到达文档,这是一项收费操作。
  • @FrankvanPuffelen 我认为它不会到达服务器来获取 ID。正如文档所述,它从后备快照数组中获取它(顺便说一句,这是您提供给适配器的查询的结果)
【解决方案2】:
holder.itemView.setOnClickListener { v ->
            Toast.makeText(v.context, snapshots.getSnapshot(position).id , Toast.LENGTH_SHORT).show()

        }

这来自 BindviewHolder

【讨论】:

    【解决方案3】:

    在 OnBindViewHolder 中使用它

    String DocID = Objects.requireNonNull (getCurrentList ()).snapshot ().get (position).getId ();
    

    如果您使用 items.class,您可以使用 getter 和 @DocumentID 创建一个字符串。

    private String docID; 
    
    @DocumentId
    public String getDocID() {
    return docID;
    }
    

    然后在onBindViewHolder中调用这个

    protected void onBindViewHolder(@NonNull @NotNull ViewHolder holder, int position, @NonNull @NotNull Items model) {
    model.getDocId();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-15
      • 2021-01-20
      • 2020-09-29
      • 2015-11-18
      • 2022-12-05
      • 1970-01-01
      • 2020-01-17
      • 2019-04-20
      相关资源
      最近更新 更多