java - 使用 FirestorePagingAdapter 的 SnapshotParser

标签 java android firebase google-cloud-firestore firebaseui

我试图在我的模型中包含文档的 id,但是当我访问它时,id 的值为 null

在 fragment/Activity 中:

public class MyEventsFragment extends Fragment {

    private OnFragmentInteractionListener mListener;
    private FirestorePagingAdapter mAdapter;
    private FirebaseFirestore mFirebaseFirestore;

    public MyEventsFragment() {
        // Required empty public constructor
    }

    public static MyEventsFragment newInstance() {
        return new MyEventsFragment();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mFirebaseFirestore = FirebaseFirestore.getInstance();

        Query query = mFirebaseFirestore.collection("events");

        PagedList.Config config = new PagedList.Config.Builder()
                .setEnablePlaceholders(false)
                .setPrefetchDistance(10)
                .setPageSize(20)
                .build();

        FirestorePagingOptions<Event> options = new FirestorePagingOptions.Builder<Event>()
                .setLifecycleOwner(this)
                .setQuery(query, config, new SnapshotParser<Event>() {
                    @NonNull
                    @Override
                    public Event parseSnapshot(@NonNull DocumentSnapshot snapshot) {
                        Event evt = new Event(
                                snapshot.getId(),
                                snapshot.getString("titre"),
                                snapshot.getString("sport"),
                                snapshot.getString("lieu"),
                                snapshot.get("date", Timestamp.class),
                                snapshot.get("dateLimit", Timestamp.class));
                        Log.i("TEST", evt.toString());
                        return evt;
                    }
                })
                .build();

        mAdapter = new EventFirestorePagingAdapter(options, getContext());
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_list_events, container, false);

        RecyclerView mRecyclerView = view.findViewById(R.id.recyclerViewListEvent);
        LinearLayoutManager mLayoutManager = new LinearLayoutManager(getContext());
        mRecyclerView.setLayoutManager(mLayoutManager);
        mRecyclerView.setAdapter(mAdapter);

        return view;
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString()
                + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    @Override
    public void onStart() {
        super.onStart();
        mAdapter.startListening();
    }

    @Override
    public void onStop() {
        super.onStop();
        mAdapter.stopListening();
    }

    public interface OnFragmentInteractionListener {
        void onFragmentInteraction(Uri uri);
    }
}

EventFirestorePagingAdapter(扩展 FirestorePagingAdapter):

 public class EventFirestorePagingAdapter extends FirestorePagingAdapter<Event, EventFirestorePagingAdapter.EventViewHolder> {

    private Context mContext;

    public EventFirestorePagingAdapter(@NonNull FirestorePagingOptions<Event> options, Context context) {
        super(options);
        this.mContext = context;
    }

    public class EventViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        TextView titre, sport, lieu, date;

        public EventViewHolder(@NonNull View itemView) {
            super(itemView);

            titre = itemView.findViewById(R.id.titreRecyclerView);
            sport = itemView.findViewById(R.id.sportRecyclerView);
            lieu = itemView.findViewById(R.id.lieuRecyclerView);
            date = itemView.findViewById(R.id.dateRecyclerView);

            itemView.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {
            /*for(Map.Entry<String, Object> map: getItem(getAdapterPosition()).getData().entrySet()){
                Log.i("TEST", map.getKey());
            }*/

            Event event = getItem(getAdapterPosition()).toObject(Event.class);
            Log.i("TEST", "id = " + event.getId());
            Toast.makeText(mContext, "OnClick on position : " + getAdapterPosition() + " \nTest : " + event.getTitre() + "\nId : " + event.getId(), Toast.LENGTH_LONG).show();
        }
    }

    @Override
    protected void onBindViewHolder(@NonNull EventViewHolder holder, int position, @NonNull Event model) {
        holder.titre.setText(model.getTitre());
        holder.sport.setText(model.getSport());
        holder.lieu.setText(model.getLieu());
        holder.date.setText(model.getDate().toDate().toString());
    }

    @NonNull
    @Override
    public EventViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i)     {
        View view = LayoutInflater.from(mContext).inflate(R.layout.recyclerview_card_row, viewGroup, false);
        return new EventViewHolder(view);
    }
}

事件类:

public class Event {
    private String id;
    private String titre;
    private String sport;
    private String lieu;
    private Timestamp date;
    private Timestamp dateLimit;

    public Event(){ } // Needed for Firebase

    public Event(String id, String titre, String sport, String lieu, Timestamp date, Timestamp dateLimit) {
        this.id = id;
        this.titre = titre;
        this.sport = sport;
        this.lieu = lieu;
        this.date = date;
        this.dateLimit = dateLimit;
    }

    // ... getters & setters
}

调试:

1) 测试:事件{id='c5jUGQc4c7SHzbpT6N01', titre='Final PSG/MARSEILLE', sport='Football', lieu='Bercy', date=Timestamp(seconds=1550844000, nanoseconds=0), dateLimit =时间戳(秒=1551009600,纳秒=0)}

2) 测试:id = null

Firestore 数据库:

Firestore Database

Gist with the same issue

回答:

SnapshotParser 没有像我预期的那样工作,但我发现了如何在 onClick() 中访问文档的 ID。我替换了 this line通过以下代码:

DocumentSnapshot documentSnapshot = getCurrentList().get(getAdapterPosition());
Chat chat = documentSnapshot.toObject(Chat.class);
chat.setId(documentSnapshot.getId());

最佳答案

根据您的评论:

yes, but i need to retrieve it later when i click on an item from my recyclerview

因为您正在使用 FirestorePagingAdapter 而您无法使用类似这样的东西:

String id = getSnapshots().getSnapshot(position).getId(); //Works only with FirestoreRecyclerAdapter

您需要将文档的 ID 存储为文档的属性。正如我在您的 Event 类中看到的,属性 id 存在但在数据库中没有 id 属性保存文档 ID。要解决这个问题,您需要在创建新对象时将文档的 ID 传递给 Event 构造函数,如下所示:

FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference eventsRef = rootRef.collection("events");
String id = eventsRef.document().getId();
Event event = new Event(id, titre, sport, lieu, date, dateLimit);
eventsRef.document(id).set(event);

关于java - 使用 FirestorePagingAdapter 的 SnapshotParser,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54610049/

相关文章:

java.lang.String 无法转换为 JSONObject

java - 从 Java 批量导入时覆盖 Azure Cosmos DB 中已存在的项目

android - 是否可以在 Android 模拟器上启用 TrafficStats?

android - 如何在Jetpack Compose中实现翻译动画?

java - GPS 和网络定位 android

ios - 使用 Swift 的 Firebase 推送通知在 ios 11.4 中不起作用

firebase - 如何从没有快照的 Angular firestore 文档获取 UID

java - Jframe 在 @Test JUnit 中消失

java - 取消部署应用程序时触发功能

firebase - 错误:找不到方法: 'Observable.combineLatest2'