android - ¿Cómo puedo recuperar datos de Firebase a mi adaptador?
firebase-realtime-database (3)
Mi estructura
Así que tengo una aplicación en la que los usuarios cargan publicaciones en mi adaptador. Puedo recuperar la descripción de la publicación y la imagen de la publicación, pero cuando trato de recuperar el nombre del afiche, la aplicación parece fallar, para recuperar el nombre con cada publicación hay un niño agregado a la base de datos con la identificación del cargador. Este es mi archivo de clase:
public String image_thumb;
public String user_id;
public String image_url;
public String desc;
public BlogPost(){}
public BlogPost(String user_id, String image_url, String desc, String image_thumb) {
this.user_id = user_id;
this.image_url = image_url;
this.desc = desc;
this.image_thumb = image_thumb;
}
public String getUser_id() {
return user_id;
}
public void setUser_id(String user_id) {
this.user_id = user_id;
}
public String getImage_url() {
return image_url;
}
public void setImage_url(String image_url) {
this.image_url = image_url;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String getImage_thumb() {
return image_thumb;
}
public void setImage_thumb(String image_thumb) {
this.image_thumb = image_thumb;
}
y este es algunos de mis adaptadores:
public void onBindViewHolder(final ViewHolder holder, int position) {
String desc_data = blog_list.get(position).getDesc();
holder.setDescText(desc_data);//this works
String image_url = blog_list.get(position).getImage_url();
holder.setBlogImage(image_url);//this works
String user_id = blog_list.get(position).getUser_id();
firebaseDatabase.child("Users").child(user_id).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
String userName = dataSnapshot.child("name").getValue().toString();
holder.setUserName(userName);
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
public void setUserName(String name){
blogUserName = mView.findViewById(R.id.blog_user_name);
blogUserName.setText(name);
}
Lo que básicamente quiero hacer es buscar dentro del user_id el nombre y recuperarlo dentro de mi
TextView
El siguiente código va dentro deBindviewhoder () debajo de esta línea:
String user_id = . . .. . . .
Supongo que es la forma en que se refiere a sus datos y la forma en que adjunta al oyente. Intente inicializar la referencia de la base de datos de esta manera:
DatabaseReference firebaseDatabase= FirebaseDatabase.getInstance().getReference().child("Users").child(user_id);
y ahora intenta escuchar así:
firebaseDatabase.addValueEventListener(new ValueEvent....{
onDataChange(.....){
//your same code
}
})
Es mejor no incluir ninguna llamada de Firebase dentro de su ViewBinder para la vista del reciclador. Lo que puede hacer es actualizar su BlogPost e incluir un nombre de campo con getter y setter. Luego, dentro de su actividad donde está agregando el BlogPost al adaptador de reciclador, puede buscar el nombre de usuario, agregar el nombre a la publicación del blog y notificar al adaptador sobre el cambio de datos.
En tu actividad haz esto
// adding BlogPost to list
// Create BlogPost object with the data.
blogList.add(blogPostObject)
firebaseDatabase.child("Users").child(user_id).child("name").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
blogPostObject.setName(dataSnapshot.getValue().toString());
adapter..notifyItemChanged(indexOfblogPostObject);
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
Para que funcione correctamente, le recomiendo que haga algunos cambios en su clase de modelo, así como en su código. Su clase de modelo debería verse así:
public class BlogPost {
public String imageThumb, userId, imageUrl, desc;
public BlogPost() {}
public BlogPost(String imageThumb, String userId, String imageUrl, String desc) {
this.imageThumb = imageThumb;
this.userId = userId;
this.imageUrl = imageUrl;
this.desc = desc;
}
public String getImageThumb() {return imageThumb;}
public String getUserId() {return userId;}
public String getImageUrl() {return imageUrl;}
public String getDesc() {return desc;}
}
Consulte la convención de nomenclatura de los campos y captadores.
Para que funcione, no olvides eliminar los datos antiguos y agregar uno nuevo.
Suponiendo que tiene un archivo .XML para su actividad que contiene un
RecyclerView
que se ve así:
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/recycler_view"/>
Y un archivo .XML para su archivo de elemento, que se ve así:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/image_thumb_text_view" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/user_id_text_view" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/image_url_text_view" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/desc_text_view" />
</LinearLayout>
Para mostrar sus datos en un
RecyclerView
usando un
FriebaseRecyclerAdapter
, siga los siguientes pasos:
Primero, necesita encontrar el
RecyclerView
en su actividad y configurar el
LinearLayoutManager
esta manera:
RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
Luego, debe crear la referencia raíz de su base de datos Firebase y un objeto
Query
como este:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
Query query = rootRef.child("Users");
Luego tendrás que crear un objeto
FirebaseRecyclerOptions
como este:
FirebaseRecyclerOptions<BlogPost> firebaseRecyclerOptions = new FirebaseRecyclerOptions.Builder<BlogPost>()
.setQuery(query, BlogPost.class)
.build();
En su clase de actividad, cree una clase de
holder
que se vea así:
private class BlogPostHolder extends RecyclerView.ViewHolder {
private TextView imageThumbtextView, userIdTextView, imageUrlTextView, descTextView;
BlogPostHolder(View itemView) {
super(itemView);
imageThumbtextView = itemView.findViewById(R.id.image_thumb_text_view);
userIdTextView = itemView.findViewById(R.id.user_id_text_view);
imageUrlTextView = itemView.findViewById(R.id.image_url_text_view);
descTextView = itemView.findViewById(R.id.desc_text_view);
}
void setBlogPost(BlogPost blogPost) {
String imageThumb = blogPost.getImageThumb();
imageThumbtextView.setText(imageThumb);
String userId = blogPost.getUserId();
userIdTextView.setText(userId);
String imageUrl = blogPost.getImageUrl();
imageUrlTextView.setText(imageUrl);
String desc = blogPost.getDesc();
descTextView.setText(desc);
}
}
Luego cree un adaptador que se declare como global:
private FirebaseRecyclerAdapter<BlogPost, BlogPostHolder> firebaseRecyclerAdapter;
Y ejemplifícalo en tu actividad así:
firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<BlogPost, BlogPostHolder>(firebaseRecyclerOptions) {
@Override
protected void onBindViewHolder(@NonNull BlogPostHolder blogPostHolder, int position, @NonNull BlogPost blogPost) {
blogPostHolder.setBlogPost(blogPost);
}
@Override
public BlogPostHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
return new BlogPostHolder(view);
}
};
recyclerView.setAdapter(firebaseRecyclerAdapter);
Al final, no olvide anular los siguientes dos métodos y comenzar a escuchar los cambios:
@Override
protected void onStart() {
super.onStart();
firebaseRecyclerAdapter.startListening();
}
@Override
protected void onStop() {
super.onStop();
if (firebaseRecyclerAdapter!= null) {
firebaseRecyclerAdapter.stopListening();
}
}