[英]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.