簡體   English   中英

FIREBASE:從另一個孩子那里獲取數據詳細信息

[英]FIREBASE : get data details from another child

我來就我的申請中遇到的問題尋求您的幫助。 問題是這樣的:新聞源上的帖子位於此帖子下的數據庫中 -> [postid] 位置與此捕獲相同帖子參考 ,當用戶保存帖子時,它在數據庫中的存儲方式如下:用戶 -> [用戶 ID] -> 保存 -> [帖子 ID],如您在此屏幕截圖中所見保存參考 .
我希望基於用戶保存的帖子的 id,他可以檢索這些帖子的信息詳細信息(如帖子描述)並將它們顯示在我的應用程序的片段“保存”中。 這是我嘗試做的

保存片段適配器

package com.ackerman.ubi.Adapter;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.ackerman.ubi.Model.PostModel;
import com.ackerman.ubi.R;
import com.bumptech.glide.Glide;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SaveAdapter extends RecyclerView.Adapter<SaveAdapter.ViewHolder> {

    private Context mContext;
    private List<PostModel> mPostModel;

    public SaveAdapter(Context mContext, List<PostModel> mPostModel) {
        this.mContext = mContext;
        this.mPostModel = mPostModel;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(mContext).inflate(R.layout.item_save, parent, false);
        return new SaveAdapter.ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull final ViewHolder holder, int position) {

        PostModel post = mPostModel.get(position);
        adaptSave(post, holder.post_image, holder.description, holder.price, holder.location, holder.product_state, holder.title);


    }


    @Override
    public int getItemCount() {
        return mPostModel.size();
    }

    class ViewHolder extends RecyclerView.ViewHolder {

        ImageView post_image;
        TextView description, price, location, product_state, title;

        ViewHolder(@NonNull View itemView) {
            super(itemView);

            post_image = itemView.findViewById(R.id.post_image);
            description = itemView.findViewById(R.id.description);
            price = itemView.findViewById(R.id.price);
            location = itemView.findViewById(R.id.location);
            product_state = itemView.findViewById(R.id.product_state);
            title = itemView.findViewById(R.id.title);

        }
    }

    //END OF ADAPTER SECTION

    //METHOD SECTION

    /**
     * Methode permettat d'adapter les sauvegarde
     *
     * @param post
     * @param postImage
     * @param description
     * @param price
     * @param location
     * @param productState
     * @param title
     */
    private void adaptSave(final PostModel post, final ImageView postImage, final TextView description, final TextView price, final TextView location, final TextView productState, final TextView title) {

        Glide.with(mContext).load(post.getPostimage()).into(postImage);

        //description.setText(post.get("description").toString());
//        price.setText(post.get("price").toString());
//        location.setText(post.get("location").toString());
//        productState.setText(post.get("product_state").toString());
//        title.setText(post.get("title").toString());
//        description.setText(post.getDescription());
//        title.setText(post.getTitle());
//
//        price.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.ic_price_tag_post, 0, 0);
//        price.setText(post.getPrice());
//
//        location.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.ic_placeholder_post, 0, 0);
//        location.setText(post.getLocation());
//
//        getProductState(post, productState);

    }

    /**
     * Methode permettant de verifier l'etat du produit
     *
     * @param post
     * @param productState
     */
    private void getProductState(PostModel post, TextView productState) {
        String product_state = post.getProduct_state();

        if (product_state.equals("Neuf")) {
            productState.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.ic_box_new_post, 0, 0);
        } else {
            productState.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.ic_box_used_post, 0, 0);

        }
    }

}

保存片段

package com.ackerman.ubi.Fragment;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.ackerman.ubi.Adapter.SaveAdapter;
import com.ackerman.ubi.Model.PostModel;
import com.ackerman.ubi.R;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import es.dmoral.toasty.Toasty;

public class SaveFragment extends Fragment {

    private List<PostModel> saveList;
    private SaveAdapter saveAdapter;

    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_save, container, false);


        RecyclerView recyclerView = view.findViewById(R.id.recycler_view);
        recyclerView.setHasFixedSize(true);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
        linearLayoutManager.setReverseLayout(true);
        linearLayoutManager.setStackFromEnd(true);
        recyclerView.setLayoutManager(linearLayoutManager);
        saveList = new ArrayList<>();
        saveAdapter = new SaveAdapter(getContext(), saveList);
        recyclerView.setAdapter(saveAdapter);

        getSaves();
        return view;
    }

    /**
     * Methode permettant de recuperer toute les sauvegardes de l'utilisateur
     */
    private void getSaves() {

        String userid = FirebaseAuth.getInstance().getCurrentUser().getUid();       //Recuperation de l'ID de l'utilisateur

        //Reference de l'emplacement des posts, Users -> ID de l'utilisateur -> saves
        DatabaseReference saveReference = FirebaseDatabase.getInstance().getReference("Users").child(userid).child("saves");

        saveReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                saveList.clear();
                for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                    PostModel save = snapshot.getValue(PostModel.class);
                    saveList.add(save);
                    saveAdapter.notifyDataSetChanged();

                }
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });
    }


}

后模型

package com.ackerman.ubi.Model;

public class PostModel {
    //Ensemble des attribus que peut avoir un post
    private String postid, postimage, description, publisher, location, price, product_state, title;

    //Constructeur vide (Obligatoire(pour une initialisation))
    public PostModel() {

    }

    /**
     * Constructeur contenant les attributs de nos post
     *
     * @param postid
     * @param postimage
     * @param description
     * @param publisher
     * @param location
     * @param price
     * @param product_state
     * @param title
     */
    public PostModel(String postid, String postimage, String description, String publisher, String location, String price, String product_state, String title) {
        this.postid = postid;
        this.postimage = postimage;
        this.description = description;
        this.publisher = publisher;
        this.location = location;
        this.price = price;
        this.product_state = product_state;
        this.title = title;
    }

    //Les getters et les setters
    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getLocation() {
        return location;
    }

    public void setLocation(String location) {
        this.location = location;
    }

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }

    public String getProduct_state() {
        return product_state;
    }

    public void setProduct_state(String product_state) {
        this.product_state = product_state;
    }

    public String getPostid() {
        return postid;
    }

    public void setPostid(String postid) {
        this.postid = postid;
    }

    public String getPostimage() {
        return postimage;
    }

    public void setPostimage(String postimage) {
        this.postimage = postimage;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getPublisher() {
        return publisher;
    }

    public void setPublisher(String publisher) {
        this.publisher = publisher;
    }
}

但我收到這個錯誤。 我得到的錯誤

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.ackerman.ubi, PID: 6313
    com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.String to type com.ackerman.ubi.Model.PostModel
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertBean(com.google.firebase:firebase-database@@19.1.0:418)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(com.google.firebase:firebase-database@@19.1.0:214)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertToCustomClass(com.google.firebase:firebase-database@@19.1.0:79)
        at com.google.firebase.database.DataSnapshot.getValue(com.google.firebase:firebase-database@@19.1.0:203)
        at com.ackerman.ubi.Fragment.SaveFragment$1.onDataChange(SaveFragment.java:73)
        at com.google.firebase.database.core.ValueEventRegistration.fireEvent(com.google.firebase:firebase-database@@19.1.0:75)
        at com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database@@19.1.0:63)
        at com.google.firebase.database.core.view.EventRaiser$1.run(com.google.firebase:firebase-database@@19.1.0:55)
        at android.os.Handler.handleCallback(Handler.java:751)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6688)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)

錯誤發生在這一行“Postmodel save = snapshot.getValue (PostModel.class);” 在 SaveFragment 中

如果毫不猶豫地問我問題,我希望我是可以理解的。 謝謝

看起來錯誤來自這一行:

PostModel save = snapshot.getValue(PostModel.class);

這一行從FirebaseDatabase.getInstance().getReference("Users").child(userid).child("saves")加載數據,這是路徑/Users/$uid/saves 在屏幕截圖中的該路徑下,我看到了這樣的結構:

在此處輸入圖片說明

因此,當您遍歷dataSnapshot.getChildren() ,每個單獨的值都只是一個字符串。 您的PostModel類具有的屬性遠多於此位置,這就是 Firebase 告訴您它Can't convert object of type java.lang.String to type com.ackerman.ubi.Model.PostModel

如果要加載此 ID 引用的帖子,則需要對數據庫進行額外調用:

String modelKey = snapshot.getValue(String.class); 
DatabaseReference postRef = FirebaseDatabase.getInstance().getReference("Posts").child(modelKey);
postRef.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot postSnapshot) {
        PostModel save = postSnapshot.getValue(PostModel.class);
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        throw databaseError.toException();
    }
}

暫無
暫無

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

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