使用 FirebaseUI 将子集合中的数据放入第二个布局中

Posted

技术标签:

【中文标题】使用 FirebaseUI 将子集合中的数据放入第二个布局中【英文标题】:Putting data from a subcollection in a second Layout with FirebaseUI 【发布时间】:2020-11-07 17:47:56 【问题描述】:

我想在新的 RecyclerView 中打开 Firebase 子集合的数据。 Main Activity 有一个 RecyclerView,其中填充了来自第一个集合的数据,第二个 Activity 应通过单击其中一个项目打开。第二个 Activity 将具有第二个 RecyclerView。我的主要活动工作正常,我可以看到我的所有数据。但是当我点击其中一项时,我的应用程序崩溃了。

这是我的 MainActivity

private FirebaseFirestore db = FirebaseFirestore.getInstance();
private CollectionReference notebookRef = db.collection("Notebook");
private KisteAdapter adapter;

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


    FloatingActionButton buttonAddKiste = findViewById(R.id.button_add_kiste);
    buttonAddKiste.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View v) 
            startActivity(new Intent(MainActivity.this, NewKisteActivity.class));
        
    );

    setUpRecyclerView();


private void setUpRecyclerView()
    Query query = notebookRef.orderBy("priority", Query.Direction.DESCENDING);
    FirestoreRecyclerOptions<Kiste> options = new FirestoreRecyclerOptions.Builder<Kiste>()
            .setQuery(query, Kiste.class)
            .build();
    adapter = new KisteAdapter(options);
    final RecyclerView recyclerView = findViewById(R.id.recycler_view_kiste);
    recyclerView.setHasFixedSize(true);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    recyclerView.setAdapter(adapter);

    new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT |ItemTouchHelper.RIGHT) 
        @Override
        public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) 
            return false;
        

        @Override
        public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) 
            adapter.deleteKiste(viewHolder.getAdapterPosition());
            final DocumentReference docRef = adapter.getSnapshots().getSnapshot(viewHolder.getAdapterPosition()).getReference();
            final Kiste kiste = adapter.getSnapshots().getSnapshot(viewHolder.getAdapterPosition()).toObject(Kiste.class);

            Snackbar.make(recyclerView, "Item deleted", Snackbar.LENGTH_LONG)
                    .setAction("Undo", new View.OnClickListener() 
                        @Override
                        public void onClick(View v) 
                            docRef.set(kiste);
                        

                    ).show();
        

        @Override
        public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) 
            new RecyclerViewSwipeDecorator.Builder(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
                    .addBackgroundColor(ContextCompat.getColor(MainActivity.this, R.color.colorAccent))
                    .addActionIcon(R.drawable.ic_delete_)
                    .create()
                    .decorate();
            super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
        
    ).attachToRecyclerView(recyclerView);

    adapter.setOnKisteClickListen(new KisteAdapter.onItemClickListener() 
        @Override
        public void onKisteClick(DocumentSnapshot documentSnapshot, int position) 
            final DocumentReference docRef = documentSnapshot.getReference();
            final CollectionReference colRef = documentSnapshot.getReference().collection("A");
            final Intent intent = new Intent(MainActivity.this,SecondaryActivity.class);
            colRef.get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() 
                @Override
                public void onSuccess(QuerySnapshot queryDocumentSnapshots) 
                    if (queryDocumentSnapshots.isEmpty())
                        colRef.add(new Item("DFB","SGRDG",5));

                        /*intent.putExtra("Document Reference",docRef.getId());
                        intent.putExtra("Collection Reference",colRef.getId());*/
                        startActivity(intent);

                    
                    else 
                        startActivity(intent);

                    
                
            );
        
    );



@Override
protected void onStart() 
    super.onStart();
    adapter.startListening();

@Override
protected void onStop() 
    super.onStop();
    adapter.stopListening();

这是第一个 RecyclerView 得到的 Class Kiste

public class Kiste 
private String title;
private int priority;

public Kiste()



public Kiste(String title, int priority)
    this.title= title;
    this.priority = priority;


public String getTitle() 
    return title;


public int getPriority() 
    return priority;

这是适配器

public class KisteAdapter extends FirestoreRecyclerAdapter<Kiste, KisteAdapter.KisteHolder> 
private onItemClickListener listener;

public KisteAdapter(@NonNull FirestoreRecyclerOptions<Kiste> options) 
    super(options);


@Override
protected void onBindViewHolder(@NonNull KisteHolder holder, int position, @NonNull Kiste model) 
        holder.textViewTitle.setText(model.getTitle());
        holder.textViewPriority.setText(String.valueOf(model.getPriority()));



@NonNull
@Override
public KisteHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) 
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.kiste_item,parent,false);
    return new KisteHolder(v);


public void deleteKiste(int position)
    getSnapshots().getSnapshot(position).getReference().delete();


class KisteHolder extends RecyclerView.ViewHolder
TextView textViewTitle;
TextView textViewPriority;
public KisteHolder(@NonNull View itemView) 
    super(itemView);
    textViewTitle = itemView.findViewById(R.id.text_view_title);
    textViewPriority = itemView.findViewById(R.id.text_view_priority);

    itemView.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View v) 
            int position = getAdapterPosition();
            if (position != RecyclerView.NO_POSITION && listener!= null)
                listener.onKisteClick(getSnapshots().getSnapshot(position),position);
            
        
    );

public interface onItemClickListener 
    void onKisteClick(DocumentSnapshot documentSnapshot, int position);


public void setOnKisteClickListen (onItemClickListener listener) this.listener = listener;

因为这对我有用,所以我尝试对子集合做同样的事情(因为我仍在测试它是否可以工作,所以我只使用了一个我知道存在的 DocumentPath),但正如我在上面所说的那样,应用程序不断崩溃。

这是第二个活动

public class SecondaryActivity extends AppCompatActivity 


private FirebaseFirestore db = FirebaseFirestore.getInstance();
private CollectionReference colRef = db.collection("Notebook").document(
                        "JGBzWBwCASivfAjuF8xE").collection("A");

private ItemAdapter adapter;

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_secondary);


    FloatingActionButton buttonAddItem = findViewById(R.id.button_add_item);

    setupRecyclerView();



private void setupRecyclerView()
    Query query2 = colRef.orderBy("priority", Query.Direction.DESCENDING);
    FirestoreRecyclerOptions<Item> options = new FirestoreRecyclerOptions.Builder<Item>()
            .setQuery(query2, Item.class)
            .build();

    adapter = new ItemAdapter(options);
    final RecyclerView recyclerView = findViewById(R.id.recycler_view_item);
    recyclerView.setHasFixedSize(true);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    recyclerView.setAdapter(adapter);


@Override
protected void onStart() 
    super.onStart();
    adapter.startListening();

@Override
protected void onStop() 
    super.onStop();
    adapter.stopListening();

类项:

public class Item 
//private Bitmap imageItem;
private String itemName;
private String itemQuantity;
private int priority;

public Item()



public Item( String itemName, String itemQuantity, int priority)
    //this.imageItem = imageViewItem;
    this.itemName = itemName;
    this.itemQuantity = itemQuantity;
    this.priority = priority;


/*public Bitmap getImageItem() 
    return imageItem;
*/

public String getItemName() 
    return itemName;


public String getItemQuantity() 
    return itemQuantity;


public int getPriority() 
    return priority;

和适配器:

public class ItemAdapter extends FirestoreRecyclerAdapter<Item, ItemAdapter.ItemHolder> 



public ItemAdapter(@NonNull FirestoreRecyclerOptions<Item> options) 
    super(options);


@Override
protected void onBindViewHolder(@NonNull ItemHolder holder, int position, @NonNull Item model) 
    //holder.imageViewItem.setImageBitmap(model.getImageItem());
    holder.textViewTitle.setText(model.getItemName());
    holder.textViewQuantity.setText(model.getItemQuantity());
    holder.textViewPriority.setText(String.valueOf(model.getPriority()));


@NonNull
@Override
public ItemHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) 
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_item,parent,false);
    return new ItemHolder(v);


class ItemHolder extends RecyclerView.ViewHolder
    //ImageView imageViewItem;
    TextView textViewTitle;
    TextView textViewQuantity;
    TextView textViewPriority;
    public ItemHolder(@NonNull View itemView)
        super(itemView);
        //imageViewItem.findViewById(R.id.image_view_item);
        textViewTitle.findViewById(R.id.text_view_item_name);
        textViewQuantity.findViewById(R.id.text_view_item_quantity);
        textViewPriority.findViewById(R.id.text_view_priority2);


    

如果有人能帮我找出问题所在,我将不胜感激。

【问题讨论】:

您在控制台中遇到的错误是什么? java.lang.NullPointerException:尝试在 guellouzdaniels.android.wpf.hsh 的空对象引用上调用虚拟方法“android.view.View android.widget.TextView.findViewById(int)”。 abschlussaufgabe.ItemAdapter$ItemHolder.(ItemAdapter.java:47) 在 guellouzdaniels.android.wpf.hsh.abschlussaufgabe.ItemAdapter.onCreateViewHolder(ItemAdapter.java:36) 在 guellouzdaniels.android.wpf.hsh.abschlussaufgabe.ItemAdapter。 onCreateViewHolder(ItemAdapter.java:16) 这就是我的想法 让我知道我发布的答案是否足够或者您是否需要进一步的帮助:) 【参考方案1】:

感谢您在控制台中指出错误,现在我们可以更轻松地查看问题所在,而无需阅读您的整个代码:D

您的 ItemAdapter 类的第 47 行出现错误。我无法确切看到它是哪一行,但我确定错误在您的 ViewHolder 中。

class ItemHolder extends RecyclerView.ViewHolder
    //ImageView imageViewItem;
    TextView textViewTitle;
    TextView textViewQuantity;
    TextView textViewPriority;
    public ItemHolder(@NonNull View itemView)
        super(itemView);
        //imageViewItem.findViewById(R.id.image_view_item);

THESE LINES OF CODE -----------------------------------------------------------------
        textViewTitle.findViewById(R.id.text_view_item_name);
        textViewQuantity.findViewById(R.id.text_view_item_quantity);
        textViewPriority.findViewById(R.id.text_view_priority2);
-------------------------------------------------------------------------------------

    

将它们替换为:

this.textViewTitle = (TextView) itemView.findViewById(R.id.text_view_item_name); // and so on...

你可以看看这个例子:

https://www.javatpoint.com/android-recyclerview-list-example

【讨论】:

以上是关于使用 FirebaseUI 将子集合中的数据放入第二个布局中的主要内容,如果未能解决你的问题,请参考以下文章

如何从 React JS 中的 firebase 文档的所有子集合中获取数据? [复制]

使用 CollectionGroupQuery 的子集合中的 Firestore 写入限制

Flutter : 检查子集合中是不是有特定的数据

如何根据子集合中的值选择对象?

从多个子集合中获取文档 - Firebase [重复]

FireStore 文档如何在子集合中读取计算