This question already has an answer here:
Sort firebase data in descending order using negative timestamp
(1 answer)
Closed 5 years ago.
I have a database structure like this (sample):
ID_EMPRESA
-name:
-adress:
-status: Aberto
-timestamp: 0154254521
-status_timestamp: Aberto_0154254521
I need to populate my RecyclerView with data from a Firebase reference
Since it is not possible to work with multiple queries when querying Firebase data, according to the structure of the database I tried the following filter:
mDatabase.child(ID_EMPRESA).orderByChild("status_timeStamp").startAt("Open").endAt("Open\uf8ff")
So I retrieve the data that has status: Open
Code RecyclerDapter:
FirebaseRecyclerAdapter<CardPedidos_row, CardPedidosViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<CardPedidos_row, CardPedidosViewHolder>(
CardPedidos_row.class,
R.layout.card_agendamentos_row,
CardPedidosViewHolder.class,
mDatabase.child(ID_EMPRESA).orderByChild("status_timeStamp").startAt("Open").endAt("Open\uf8ff")
)
How could I recover the data in descending order, since it already has the timestamp stored.
As it is, it is bringing Ascending
FullCode - Fragment:
public class PedidosTab1 extends Fragment {
private RecyclerView mCardPedidos;
private DatabaseReference mDatabaseEmpresa;
private DatabaseReference mDatabaseAgendamentos;
private FirebaseAuth mAuth;
private FirebaseUser mCurrentUser;
private TextView mTextPadrao;
private Query query;
public PedidosTab1() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_pedidos_tab1, container, false);
/*Recuperando instancia do Firebase*/
mAuth = FirebaseAuth.getInstance();
mCurrentUser = mAuth.getCurrentUser();
mDatabaseEmpresa = FirebaseDatabase.getInstance().getReference().child("Empresas").child(mCurrentUser.getUid());
mDatabaseAgendamentos = FirebaseDatabase.getInstance().getReference().child("Vendas_Empresas");
/*Atributos tela*/
mTextPadrao = (TextView) view.findViewById(R.id.tvPedTab1_textPadrao);
/*RecyclerView*/
mCardPedidos = (RecyclerView) view.findViewById(R.id.cardListaPedidos);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
linearLayoutManager.setReverseLayout(true);
linearLayoutManager.setStackFromEnd(true);
mCardPedidos.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
carregarPedidos();
return view;
}
private void carregarPedidos() {
mDatabaseAgendamentos.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.child(mCurrentUser.getUid()).exists()){
carregarDadosRecycler();
} else {
mTextPadrao.setVisibility(View.VISIBLE);
mCardPedidos.setVisibility(View.GONE);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private void carregarDadosRecycler() {
FirebaseRecyclerAdapter<CardPedidos_row, CardPedidosViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<CardPedidos_row, CardPedidosViewHolder>(
CardPedidos_row.class,
R.layout.card_agendamentos_row,
CardPedidosViewHolder.class,
mDatabaseAgendamentos.child(mCurrentUser.getUid()).orderByChild("status_timeStamp").startAt("Aberto").endAt("Aberto\uf8ff")
) {
#Override
protected void populateViewHolder(final CardPedidosViewHolder viewHolder, final CardPedidos_row model, int position) {
final String pedido_key = getRef(position).getKey();
String nome_servico = model.getEmpresa_nome();
String nome_empresa = model.getEmpresa_nome();
final String id_empresa = model.getEmpresa_id();
String valor_servico = model.getServico_valor();
String hora = model.getAgenda_hora();
String data = model.getAgenda_data();
String status = model.getStatus_situacao();
String timeStamp = model.getTimestamp_criacaoDt();
viewHolder.setServico_nome(model.getServico_nome());
viewHolder.setAgenda_data(model.getAgenda_data());
viewHolder.setAgenda_hora(model.getAgenda_hora());
viewHolder.setServico_valor(model.getServico_valor());
viewHolder.setEmpresa_nome(model.getEmpresa_nome());
viewHolder.setStatus_situacao(model.getStatus_situacao());
viewHolder.setTimestamp_criacaoDt(model.getTimestamp_criacaoDt());
/*Clique na View*/
viewHolder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
/*Intent detalhePedido = new Intent(getActivity().getApplication(), DetalhePedido.class);
detalhePedido.putExtra("id_empresa", id_empresa);
detalhePedido.putExtra("id_venda", pedido_key);
startActivity(detalhePedido);*/
Intent detalhePedido = new Intent(getActivity().getApplication(), DetalhePedido.class);
detalhePedido.putExtra("id_pedido", pedido_key);
startActivity(detalhePedido);
}
});
}
};
mCardPedidos.setAdapter(firebaseRecyclerAdapter);
}
public static class CardPedidosViewHolder extends RecyclerView.ViewHolder{
View mView;
public CardPedidosViewHolder ( View itemView ){
super(itemView);
mView = itemView;
}
public void setServico_nome(String servico_nome){
TextView cardNome_servico = (TextView) mView.findViewById(R.id.tvNomeServico_CardAg);
cardNome_servico.setText(servico_nome);
}
public void setEmpresa_nome(String empresa_nome){
TextView cardNome_empresa = (TextView) mView.findViewById(R.id.tvNomeEmpresa_CardAg);
cardNome_empresa.setText(empresa_nome);
}
public void setServico_valor(String servico_valor){
TextView cardValor_servico = (TextView) mView.findViewById(R.id.tvValor_CardAg);
cardValor_servico.setText(servico_valor);
}
public void setAgenda_data(String agenda_data){
TextView cardData = (TextView) mView.findViewById(R.id.tvData_CardAg);
cardData.setText(agenda_data);
}
public void setAgenda_hora(String agenda_hora){
TextView cardHora = (TextView) mView.findViewById(R.id.tvHora_CardAg);
cardHora.setText(agenda_hora);
}
public void setStatus_situacao(String status_situacao){
TextView cardStatus = (TextView) mView.findViewById(R.id.tvStatus_CardAg);
cardStatus.setText(status_situacao);
}
public void setTimestamp_criacaoDt(String timestamp_criacao){
TextView cardTimeStamp = (TextView) mView.findViewById(R.id.tvTimeStamp);
cardTimeStamp.setText(timestamp_criacao);
}
}
}
This should work!
Add the getItem(int position) method to your FirebaseRecyclerAdapter as:
#Override
public CardPedidos_row getItem(int position) {
return super.getItem(getCount() - position - 1);
}
This will return a list in reverse order.
FirebaseRecyclerAdapter<CardPedidos_row, CardPedidosViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<CardPedidos_row,CardPedidosViewHolder>(
CardPedidos_row.class,
R.layout.card_agendamentos_row,
CardPedidosViewHolder.class,
mDatabaseAgendamentos.child(mCurrentUser.getUid()).orderByChild("status_timeStamp").startAt("Aberto").endAt("Aberto\uf8ff")
) {
#Override
public CardPedidos_row getItem(int position) {
return super.getItem(getCount() - position - 1);
}
#Override
protected void populateViewHolder(final CardPedidosViewHolder viewHolder, final CardPedidos_row model, int position) { ....
Related
I'm trying to make a comment system for posts on my social media app. In my database each post has a section inside of "comments" table, like so:
"hypno--######" is the title of the social media post. It Contains the comment, user id of the user who posted the comment, and a unixtimestamp when the comment was posted. Each comment is titled after the time it was posted.
This is the Comment class
public class comment {
public String uID;
public String comment_t;
public long unixTimestamp;
public comment() {
// Default constructor required for calls to DataSnapshot.getValue(User.class)
}
public comment(String uID, String comment_t, long unixTimestamp) {
this.uID = uID;
this.comment_t = comment_t;
this.unixTimestamp = unixTimestamp;
}
public String getuID() {
return uID;
}
public void setuID(String uID) {
this.uID = uID;
}
public String getComment() {return comment_t;}
public void setComment() {this.comment_t = comment_t; }
public long getUnixTimestamp() {
return unixTimestamp;
}
}
This is the Comment Adapter:
Public class Adapter_Comment extends FirebaseRecyclerAdapter<comment, Adapter_Comment.ViewHolder_com> {
private DatabaseReference mDatabase;
private static final String TAG = "RecyclerViewAdapter";
private Context mContext;
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
private static AppCompatActivity unwrap(Context context) {
while (!(context instanceof Activity) && context instanceof ContextWrapper) {
context = ((ContextWrapper) context).getBaseContext();
}
return (AppCompatActivity) context;
}
public Adapter_Comment(#NonNull FirebaseRecyclerOptions<comment> options) {
super(options);
//this.mContext = mContext;
}
#NonNull
#Override
public ViewHolder_com onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_comment, parent, false);
mDatabase = FirebaseDatabase.getInstance().getReference();
return new ViewHolder_com(view);
}
#Override
protected void onBindViewHolder(#NonNull ViewHolder_com holder, int position, #NonNull comment model) {
mDatabase = FirebaseDatabase.getInstance().getReference();
long dv = model.getUnixTimestamp()*-1000;
Date df = new java.util.Date(dv);
String vv = new SimpleDateFormat("MM dd, yyyy hh:mma", Locale.ENGLISH).format(df);
holder.time.setText(vv);
String com = model.getComment();
holder.comment_text.setText(com);
mDatabase.child("users").child(model.getuID()).child("profileUrl").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.exists())
{
final String picUrl = snapshot.getValue(String.class);
Glide.with(holder.postPfp.getContext()).load(picUrl).into(holder.postPfp);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) { }
});
holder.postPfp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//AppCompatActivity activity = (AppCompatActivity) v.getContext();
AppCompatActivity activity = unwrap(v.getContext());
Fragment OtherProfileFragment = new OtherProfileFragment();
Bundle bundle = new Bundle();
bundle.putString("key", model.getuID());
OtherProfileFragment.setArguments(bundle);
activity.getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, OtherProfileFragment).addToBackStack(null).commit();
}
});
}
public class ViewHolder_com extends RecyclerView.ViewHolder {
TextView comment_text;
CircleImageView postPfp;
TextView time;
RelativeLayout comment_layout;
public ViewHolder_com(#NonNull View itemView) {
super(itemView);
postPfp = itemView.findViewById(R.id.iv_comment_icon);
comment_text = itemView.findViewById(R.id.tv_comment_text);
time = itemView.findViewById(R.id.tv_comment_time);
comment_layout = itemView.findViewById(R.id.comment_layout);
}
}
}
This is Comment Fragment:
public class CommentFragment extends Fragment {
private DatabaseReference mDatabase;
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
View view;
String value;
RecyclerView recyclerView;
Query query;
TextView comment_text;
long unixTime = System.currentTimeMillis() / 1000L;
public long globalUnix;
Button comment_post;
String comment_string;
Adapter_Comment adapter;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_comment, container, false);
value = getArguments().getString("key");
mDatabase = FirebaseDatabase.getInstance().getReference();
recyclerView = view.findViewById(R.id.recyclerv_comment);
comment_text = view.findViewById(R.id.tv_comment_type);
comment_post = view.findViewById(R.id.btn_comment_post);
globalUnix = (unixTime * -1);
comment_post.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(comment_text.getText().toString() == NULL){
Toast.makeText(getActivity(), "No Comment Typed", Toast.LENGTH_LONG).show();
}
else{
comment com = new comment();
com.uID = user.getUid();
com.comment_t = comment_text.getText().toString();
com.unixTimestamp = globalUnix;
mDatabase.child("comments").child(value).child(globalUnix + "").setValue(com);
}
}
});
initRecyclerView();
return view;
}
private void initRecyclerView(){
//Log.d(TAG, "initRecyclerView: init recyclerView");
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
recyclerView.setLayoutManager(layoutManager);
query = FirebaseDatabase.getInstance().getReference().child("comments").orderByValue();
FirebaseRecyclerOptions<comment> options = new FirebaseRecyclerOptions.Builder<comment>().setQuery(query, comment.class).build();
adapter = new Adapter_Comment(options);
recyclerView.setAdapter(adapter);
adapter.startListening();
adapter.notifyDataSetChanged();
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
Inside of the adapter I'm using the comment model, to get the uID, comment and timestamp to fill the holder, however when i set these values im getting null values. Is there something im missing when trying to connect the adapter/firebase and model/holder?
long dv = model.getUnixTimestamp()*-1000;
Date df = new java.util.Date(dv);
String vv = new SimpleDateFormat("MM dd, yyyy hh:mma", Locale.ENGLISH).format(df);
holder.time.setText(vv);
String com = model.getComment();
holder.comment_text.setText(com);
mDatabase.child("users").child(model.getuID()).child("profileUrl").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.exists())
{
final String picUrl = snapshot.getValue(String.class);
Glide.with(holder.postPfp.getContext()).load(picUrl).into(holder.postPfp);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) { }
});
There's really too much going on in here, but...
As far as I can see you're creating a FirebaseUI adapter on FirebaseDatabase.getInstance().getReference().child("comments"). FirebaseUI adapters show the direct child nodes of the node you pass in, so in your case it'll create one view for the hypno---...196 node. You're trying to read a Comment object from there, but don't exist until one level lower in your JSON.
So you can:
Either show the comments for one post, by basing the adapter off of that. So: FirebaseDatabase.getInstance().getReference().child("comments").child("hypno---...196") (which the real key in there).
Or you can show one piece of information about each post, for example its key.
If you want to show a flat list of comments for all posts through the FirebaseUI adapter, you'll have to store a flat list of comments across all posts in your database too.
I have a problem with retrieving specific data from Firebase Realtime Database. My problem is that I want to display in RecyclerView just the materials that has the Course_ID (as you can see in the image below) equals to the Course_ID (see Course -> Teacher-Courses in Firebase). How can I accomplish that thing? I will attach the code used in the RecyclerView and the class that contains the model.
As a mention: 1.I have tried to add all the course id's from Firebase and store them to a List, but the app doesn't show anything and 2. In another class I have an Intent that sends me here and also send a extra String with Course_ID that I have accesed.
I am waiting for your responses. Thank you!
FileMaterial.class
public class FileMaterial {
private String Course_ID;
private String Denumire_material;
private String Locatie_material;
private String Teacher_ID;
public FileMaterial() {
}
public FileMaterial(String course_ID, String denumire_material, String locatie_material, String teacher_ID) {
Course_ID = course_ID;
Denumire_material = denumire_material;
Locatie_material = locatie_material;
Teacher_ID = teacher_ID;
}
public String getCourse_ID() {
return Course_ID;
}
public void setCourse_ID(String course_ID) {
Course_ID = course_ID;
}
public String getDenumire_material() {
return Denumire_material;
}
public void setDenumire_material(String denumire_material) {
Denumire_material = denumire_material;
}
public String getLocatie_material() {
return Locatie_material;
}
public void setLocatie_material(String locatie_material) {
Locatie_material = locatie_material;
}
public String getTeacher_ID() {
return Teacher_ID;
}
public void setTeacher_ID(String teacher_ID) {
Teacher_ID = teacher_ID;
}
CourseMaterial.class
public class CourseMaterial extends AppCompatActivity {
private RecyclerView recyclerView;
private DatabaseReference reference, userReference;
private FirebaseAuth mAuth;
FirebaseRecyclerOptions<FileMaterial> options;
FirebaseRecyclerAdapter<FileMaterial, CourseMaterial.FileViewHolder> adapter;
ImageView btnAddMaterial;
ImageView deleteMaterial;
StorageReference storageReference;
FirebaseStorage firebaseStorage;
String urlReference;
String value;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_course_material);
value = getIntent().getStringExtra("course id").toString();
mAuth = FirebaseAuth.getInstance();
reference = FirebaseDatabase.getInstance().getReference().child("Materials").child(mAuth.getCurrentUser().getUid());
recyclerView = findViewById(R.id.recyclerView_fileMaterials);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
btnAddMaterial = findViewById(R.id.addMaterials);
btnAddMaterial.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(CourseMaterial.this, UploadFile.class));
}
});
}
#Override
public void onStart() {
super.onStart();
options = new FirebaseRecyclerOptions.Builder<FileMaterial>().setQuery(reference, FileMaterial.class).build();
adapter = new FirebaseRecyclerAdapter<FileMaterial, FileViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull final FileViewHolder fileViewHolder, int i, #NonNull final FileMaterial fileMaterial) {
fileViewHolder.denumire_material.setText(fileMaterial.getDenumire_material());
}
#NonNull
#Override
public FileViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.youtube_view,parent, false);
FileViewHolder fileViewHolder = new FileViewHolder(v);
return fileViewHolder;
}
};
adapter.startListening();
recyclerView.setAdapter(adapter);
}
public static class FileViewHolder extends RecyclerView.ViewHolder{
TextView denumire_material, dataMaterial;
ImageView deleteMaterial;
public FileViewHolder(#NonNull View itemView) {
super(itemView);
denumire_material = itemView.findViewById(R.id.txtDenMaterial);
deleteMaterial = itemView.findViewById(R.id.imgDeleteMaterial);
}
}
Maybe make a query and pass it to the options of the adapter:
#Override
public void onStart() {
super.onStart();
Query query = reference.orderByChild("Course_ID").equalTo(value);
options = new FirebaseRecyclerOptions.Builder<FileMaterial>().setQuery(query, FileMaterial.class).build();
.......
.......
.......
I have recyclerview recieving data from firebase and i want to make last item uploaded to be first item in the list.I'm using GridLayoutManager and want to display a pic with a text, all of this work fine but i want to make them in order like instagram, does any one know something like that ?
Here is my code
public class ItemsUser extends Fragment {
private View mMainView;
private RecyclerView mUsersList;
private String user_id;
private DatabaseReference mUserDatabase;
private FirebaseRecyclerAdapter<ItemRecycleview,UserRecycleView> firebaseRecyclerAdapter;
private DatabaseReference mDatabaseReference;
private FirebaseListAdapter<ItemRecycleview> firebaseListAdapter;
public ItemsUser() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
mMainView = inflater.inflate(R.layout.fragment_items_user, container, false);
mUsersList = (RecyclerView) mMainView.findViewById(R.id.recyclerView_profile);
mUsersList.setHasFixedSize(true);
mUsersList.setLayoutManager(new GridLayoutManager(getActivity(),3));
ProfileUser activity = (ProfileUser) getActivity();
user_id = activity.getMyData();
mDatabaseReference = FirebaseDatabase.getInstance().getReference();
mUserDatabase = FirebaseDatabase.getInstance().getReference().child("Users_photos").child(user_id);
mUserDatabase.keepSynced(true);
return mMainView;
}
#Override
public void onStart() {
super.onStart();
firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<ItemRecycleview, UserRecycleView>(
ItemRecycleview.class,
R.layout.recycleview_item,
UserRecycleView.class,
mUserDatabase
) {
#Override
protected void populateViewHolder(UserRecycleView viewHolder, ItemRecycleview model, int position) {
viewHolder.setImageName(model.getImageName());
viewHolder.setImageURL(model.getImageURL(),getContext());
viewHolder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String key = firebaseRecyclerAdapter.getRef(mUsersList.getChildLayoutPosition(v)).getKey();
Intent imageIntent = new Intent(getActivity(), ImageActivity.class);
imageIntent.putExtra("imageKey",key);
imageIntent.putExtra("user_id",user_id);
startActivity(imageIntent);
}
});
}
};
mUsersList.setAdapter(firebaseRecyclerAdapter);
}
public static class UserRecycleView extends RecyclerView.ViewHolder {
View mView;
public UserRecycleView(View itemView) {
super(itemView);
mView = itemView;
}
public void setImageName(String imageName){
TextView userNameView = (TextView) mView.findViewById(R.id.ImageNameTextView);
userNameView.setText(imageName);
}
public void setImageURL(final String imageURL,final Context ctx){
final ImageView userImageView = (ImageView) mView.findViewById(R.id.imageView);
Picasso.with(ctx).load(imageURL).networkPolicy(NetworkPolicy.OFFLINE).into(userImageView, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
Picasso.with(ctx).load(imageURL).into(userImageView);
}
});
}
}
}
and this is ItemRecyclerview:
public class ItemRecycleview {
public String imageName;
public String imageURL;
public ItemRecycleview(){
}
public ItemRecycleview(String imageName, String imageURL) {
this.imageName = imageName;
this.imageURL = imageURL;
}
public String getImageName() {
return imageName;
}
public void setImageName(String imageName) {
this.imageName = imageName;
}
public String getImageURL() {
return imageURL;
}
public void setImageURL(String imageURL) {
this.imageURL = imageURL;
}
}
hey guys i just found the answer :D
all you need to do is to add this method in firebaseRecyclerAdapter
here it's:
firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<ItemRecycleview, UserRecycleView>(
ItemRecycleview.class,
R.layout.recycleview_item,
UserRecycleView.class,
mUserDatabase
) {
#Override
public ItemRecycleview getItem(int position) {
return super.getItem(getItemCount() - 1 - position);
}
#Override
protected void populateViewHolder(UserRecycleView viewHolder, ItemRecycleview model, int position) {
viewHolder.setImageName(model.getImageName());
viewHolder.setImageURL(model.getImageURL(),getContext());
viewHolder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String key = firebaseRecyclerAdapter.getRef(mUsersList.getChildLayoutPosition(v)).getKey();
Intent imageIntent = new Intent(getActivity(), ImageActivity.class);
imageIntent.putExtra("imageKey",key);
imageIntent.putExtra("user_id",user_id);
startActivity(imageIntent);
}
});
}
};
and that will make it done
Have you tried using setReverseLayout() method to make first element last in the list
GridLayoutManager mLayoutManager = new GridLayoutManager(getActivity(),3);
mLayoutManager.setReverseLayout(true);
mLayoutManager.setStackFromEnd(true);
mUsersList.setLayoutManager(mLayoutManager);
I keep getting a null pointer exception error at the DessertAdapter class starting at the line holder.mName.setText(dessert.getName());
I've tried all methods I know and I'm still getting the same error.
Here is the Adapter class
public class DessertAdapter extends RecyclerView.Adapter<DessertAdapter.DessertVh> {
private List<Dessert> desserts = new ArrayList<>();
private static final int VIEW_TYPE_EMPTY_LIST_PLACEHOLDER = 0;
private static final int VIEW_TYPE_OBJECT_VIEW = 1;
private Context context;
#Override
public int getItemViewType(int position) {
if (desserts.isEmpty()) {
return VIEW_TYPE_EMPTY_LIST_PLACEHOLDER;
} else {
return VIEW_TYPE_OBJECT_VIEW;
}
}
public DessertAdapter(Context context,List<Dessert> desserts) {
this.context = context;
this.desserts = desserts;
}
// TODO: another placeholder stuff here
#Override
public DessertVh onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.item_dessert, parent, false);
return new DessertAdapter.DessertVh(view);
}
#Override
public void onBindViewHolder(DessertVh holder, int position) {
Dessert dessert = desserts.get(position);
System.out.println(position);
holder.mName.setText(dessert.getName());
holder.mDescription.setText(dessert.getDescription());
holder.mFirstLetter.setText(String.valueOf(dessert.getFirstLetter()));
holder.mPrice.setText(String.valueOf(dessert.getAmount()));
}
#Override
public int getItemCount() {
return desserts == null ? 0 : desserts.size();
}
public static class DessertVh extends RecyclerView.ViewHolder {
private TextView mName;
private TextView mPrice;
private TextView mDescription;
private TextView mFirstLetter;
public DessertVh(View itemView) {
super(itemView);
mName = (TextView) itemView.findViewById(R.id.txt_name);
mPrice = (TextView) itemView.findViewById(R.id.txt_price);
mDescription = (TextView) itemView.findViewById(R.id.txt_desc);
mFirstLetter = (TextView) itemView.findViewById(R.id.txt_firstletter);
}
}
Here is the class to save the data to the Dessert object
public class AddGigActivity extends AppCompatActivity {
private static String TAG = "AddGigActivity";
private ImageButton saveBtn;
private EditText gigName, gigDescrip, gigAmount;
private String userID;
private FirebaseDatabase mFirebaseDatabase;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthStateListener;
private DatabaseReference myRef;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_gig);
gigName = (EditText)findViewById(R.id.gig_name);
gigDescrip = (EditText)findViewById(R.id.gig_description);
gigAmount = (EditText) findViewById(R.id.gig_amnt);
saveBtn = (ImageButton) findViewById(R.id.mybtn_add);
mAuth = FirebaseAuth.getInstance();
mFirebaseDatabase = FirebaseDatabase.getInstance();
myRef = FirebaseDatabase.getInstance().getReference();
FirebaseUser user = mAuth.getCurrentUser();
userID = user.getUid();
saveBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
AddGig();
}
});
}
// real-time adding to the firebase database
private void AddGig(){
String name = gigName.getText().toString();
String descrip = gigDescrip.getText().toString();
String amount = gigAmount.getText().toString();
if((!TextUtils.isEmpty(name))&&(!TextUtils.isEmpty(descrip) && (!TextUtils.isEmpty(amount))) ){
FirebaseUser user = mAuth.getCurrentUser();
userID = user.getUid();
String id = myRef.push().getKey();
Dessert dessert = new Dessert( name, descrip, amount);
// myRef.child(id).setValue(dessert);
myRef.child("users").child(userID).child("Gig posts").child(id).setValue(dessert);
Toast.makeText(this, "Posted! ",Toast.LENGTH_LONG).show();
finish();
// you can still sprlit these to check for each text field
}else{
Toast.makeText(this, "One or more field(s) missing!",Toast.LENGTH_LONG).show();
}
}
And here is the main activity code snippet that displays the data from firebase on the recycler view:
public static class FeedsFragment extends Fragment {
int color;
public FeedsFragment() {
}
#SuppressLint("ValidFragment")
public FeedsFragment(int color) {
this.color = color;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dummy_fragment, container, false);
final RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.dummyfrag_scrollableview);
final FrameLayout frameLayout = (FrameLayout) view.findViewById(R.id.dummyfrag_bg);
frameLayout.setBackgroundColor(color);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity().getBaseContext());
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setHasFixedSize(true);
final List<Dessert> dessertList;
dessertList = new ArrayList<>();
//dessertList = new Dessert(context,"");
final String curtUserId = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
// DatabaseReference mDatabaseGig = rootRef.child("users").child(curtUserId).child("Gig posts");
final String id = rootRef.push().getKey();
final DessertAdapter adapter = new DessertAdapter(getContext(), dessertList);
recyclerView.setAdapter(adapter);
rootRef.addValueEventListener(new com.google.firebase.database.ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
dessertList.clear();
for(DataSnapshot gigSnapshot: dataSnapshot.getChildren()){
Dessert dessert = gigSnapshot
.child("users")
.child(curtUserId)
.child("Gig posts")
.child(id).getValue(Dessert.class);
dessertList.add(dessert);
adapter.notifyDataSetChanged();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
// possible to put progress dialogue
return view;
}
}
please would you mind taking a look at the code and help me straighten it out? Thank you.
try below Adapter class
public class DessertAdapter extends RecyclerView.Adapter<DessertAdapter.DessertVh> {
private List<Dessert> desserts;
private static final int VIEW_TYPE_EMPTY_LIST_PLACEHOLDER = 0;
private static final int VIEW_TYPE_OBJECT_VIEW = 1;
private Context context;
// TODO: placeholder stuff here
#Override
public int getItemViewType(int position) {
if (desserts.isEmpty()) {
return VIEW_TYPE_EMPTY_LIST_PLACEHOLDER;
} else {
return VIEW_TYPE_OBJECT_VIEW;
}
}
public DessertAdapter(Context context,List<Dessert> desserts) {
this.context = context;
this.desserts = desserts;
// desserts = Dessert.prepareDesserts(
// context.getResources().getStringArray(R.array.dessert_names),
// context.getResources().getStringArray(R.array.dessert_descriptions),
// context.getResources().getStringArray(R.array.dessert_amounts));
}
// TODO: another placeholder stuff here
#Override
public DessertVh onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.item_dessert, parent, false);
return new DessertAdapter.DessertVh(view);
}
#Override
public void onBindViewHolder(DessertVh holder, int position) {
holder.mName.setText(desserts.get(position).getName());
holder.mDescription.setText(desserts.get(position).getDescription());
holder.mFirstLetter.setText(String.valueOf(desserts.get(position).getFirstLetter()));
holder.mPrice.setText(String.valueOf(desserts.get(position).getAmount()));
}
#Override
public int getItemCount() {
// if nothing, return null,
// else return the number of items in the list
return desserts == null ? 0 : desserts.size();
}
public static class DessertVh extends RecyclerView.ViewHolder {
private TextView mName;
private TextView mPrice;
private TextView mDescription;
private TextView mFirstLetter;
public DessertVh(View itemView) {
super(itemView);
mName = (TextView) itemView.findViewById(R.id.txt_name);
mPrice = (TextView) itemView.findViewById(R.id.txt_price);
mDescription = (TextView) itemView.findViewById(R.id.txt_desc);
mFirstLetter = (TextView) itemView.findViewById(R.id.txt_firstletter);
}
}
Ok, so I fixed it!
here's the code
public static class UserFeedFragment extends Fragment {
int color;
public UserFeedFragment() {
}
#SuppressLint("ValidFragment")
public UserFeedFragment(int color) {
this.color = color;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dummy_fragment, container, false);
final RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.dummyfrag_scrollableview);
final FrameLayout frameLayout = (FrameLayout) view.findViewById(R.id.dummyfrag_bg);
frameLayout.setBackgroundColor(color);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity().getBaseContext());
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setHasFixedSize(true);
String curtUserId = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference()
.child("users")
.child(curtUserId)
.child("Gig posts");
final List<Dessert> dessertList = new ArrayList<Dessert>();
final DessertAdapter adapter = new DessertAdapter(getContext(), dessertList);
recyclerView.setAdapter(adapter);
rootRef.addValueEventListener(new com.google.firebase.database.ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
dessertList.clear();
for(DataSnapshot gigSnapshot: dataSnapshot.getChildren()){
Dessert dessert = gigSnapshot
.getValue(Dessert.class);
dessertList.add(dessert);
adapter.notifyDataSetChanged();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
// possible to put progress dialogue
return view;
}
}
All I had to change was here
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference()
.child("users")
.child(curtUserId)
.child("Gig posts");
then add an event listener here
rootRef.addValueEventListener(new com.google.firebase.database.ValueEventListener() {
and it worked!
I do have a minor problem though. I have two feeds fragment: UserFeed and FeedsFragments. The Userfeed gets the feeds that the current user has posted while the FeedsFragment is meant to get feeds posted by all users. I tried doing this
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference()
.child("users")
// .child(curtUserId) I commented out the id of the user but nothing happened
.child("Gig posts");
My question is : is there a way I can "direct" the reference to retrieve posts by all users?
Once again, thanks so much in advance for your help!
I'm making a simple application that shows local events happening around campus. Each event is held in a Cardview that looks like this. The red square is a placeholder for an icon to show what category of event this is.
I want to change the ImageView (the red square), depending on the value child's string value. So if the string value of the child "category" was "music", a musical note icon would be displayed instead of the red square, etc. I know I could probably use a switch statement to manually read the value of that child, and then set the ImageView based on the string value, but I don't know where to put it in my code, or if that's even the best method. What do you recommend? Here is my code for the fragment:
public class EventsFragment extends Fragment {
public String postKey;
public static class EventViewHolder extends RecyclerView.ViewHolder{
public TextView eventTitle;
public ImageView eventImage;
public ImageView eventCategory;
public TextView eventDate;
View mView;
public EventViewHolder(View v){
super(v);
mView = v;
eventTitle = (TextView)mView.findViewById(R.id.title);
eventImage = (ImageView)mView.findViewById(R.id.image);
eventCategory = (ImageView)mView.findViewById(R.id.category);
eventDate = (TextView)mView.findViewById(R.id.date);
}
public TextView getEventTitle() {
return eventTitle;
}
public void setEventTitle(TextView eventTitle) {
this.eventTitle = eventTitle;
}
}
private DatabaseReference mFirebaseDatabaseReference;
private FirebaseRecyclerAdapter<ModelClass, EventViewHolder> mFirebaseAdapter;
private RecyclerView mEventRecyclerView;
private LinearLayoutManager mLinearLayoutManager;
private static String TAG = "EventsFragment";
public static final String DATA = "Data";
//VARIABLES
private RecyclerView mBlogList;
private FirebaseDatabase database;
private DatabaseReference ref;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.events_fragment,container,false);
v.setTag(TAG);
//RV
mEventRecyclerView = (RecyclerView)v.findViewById(R.id.events_list);
//LLM
mLinearLayoutManager = new LinearLayoutManager(getActivity());
mEventRecyclerView.setLayoutManager(mLinearLayoutManager);
//DB
mFirebaseDatabaseReference = FirebaseDatabase.getInstance().getReference();
mFirebaseAdapter = new FirebaseRecyclerAdapter<ModelClass, EventViewHolder>(
ModelClass.class,
R.layout.design_row,
EventViewHolder.class,
mFirebaseDatabaseReference.child(DATA))
{
#Override
protected void populateViewHolder(EventViewHolder viewHolder, ModelClass model, final int position) {
final String post_key = getRef(position).getKey();
viewHolder.eventDate.setText(model.getDate());
viewHolder.eventTitle.setText(model.getTitle());
Picasso.with(getActivity().getApplicationContext())
.load(model.getImage())
.fit()
.into(viewHolder.eventImage);
viewHolder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
setPostKey(post_key);
mFirebaseDatabaseReference.child(DATA).child(post_key).addValueEventListener(new ValueEventListener() {
String post_info, post_title, post_image, post_category;
#Override
public void onDataChange(DataSnapshot snapshot) {
System.out.println(snapshot.getValue());
post_info = snapshot.child("info").getValue().toString();
post_title = snapshot.child("title").getValue().toString();
post_image = snapshot.child("image").getValue().toString();
post_category = snapshot.child("category").getValue().toString();
Bundle bundle = new Bundle();
bundle.putString("info", post_info);
bundle.putString("title", post_title);
bundle.putString("image", post_image);
FragmentManager fragM = getActivity().getSupportFragmentManager();
FragmentTransaction fragT = fragM.beginTransaction();
EventsExpandedFragment expand = new EventsExpandedFragment();
expand.setArguments(bundle);
fragT.replace(R.id.frame, expand);
fragT.addToBackStack("");
fragT.commit();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
});
}
};
mEventRecyclerView.setLayoutManager(mLinearLayoutManager);
mEventRecyclerView.setAdapter(mFirebaseAdapter);
return v;
}
public String getPostKey() {
return postKey;
}
public void setPostKey(String postKey) {
this.postKey = postKey;
}
}
And here is a full screenshot for reference:
I think it seems obvious that you should put the switch statement at the populateViewHolder
#Override
protected void populateViewHolder(EventViewHolder viewHolder, ModelClass model, final int position) {
switch (model.eventCategory) {
case "eventType1": {
//load your event category image
}
case "eventType2": {
//load your event category image
}
default:
break;
}
// other actions
}
Does this answer you question?