Null pointer exception on null object reference - android

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!

Related

FirebaseRecyclerAdapter model returning null values

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.

Firebase syncing method not syncing

Code
public class HomeScreen_Friends extends Fragment {
private View rootView;
private String userName;
private String UID;
private TextView noUsersText;
private ProgressDialog mProgressDialogue;
private FirebaseAuth mAuth;
private FirebaseUser currentUser;
private DatabaseReference mDatabaseReference;
private DatabaseReference mUsersDatabase;
private RecyclerView mUsersList;
private FirebaseRecyclerAdapter<AllUsersHelper, UsersViewHolder> firebaseRecyclerAdapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_friends, container, false);
noUsersText = (TextView) rootView.findViewById(R.id.noUsersText);
mUsersList = (RecyclerView) rootView.findViewById(R.id.usersList);
mUsersList.addItemDecoration(new DividerItemDecoration(getContext(),
DividerItemDecoration.HORIZONTAL));
mAuth = FirebaseAuth.getInstance();
currentUser = mAuth.getCurrentUser();
UID = mAuth.getCurrentUser().getUid();
mDatabaseReference = FirebaseDatabase.getInstance().getReference().child("Friends").child(UID);
mDatabaseReference.keepSynced(true);
mUsersDatabase = FirebaseDatabase.getInstance().getReference().child("UserData");
mUsersDatabase.keepSynced(true);
mProgressDialogue = new ProgressDialog(getActivity());
mProgressDialogue.setMessage("Loading...");
mProgressDialogue.show();
mUsersList.setLayoutManager(new LinearLayoutManager(getActivity()));
FirebaseRecyclerOptions<AllUsersHelper> options =
new FirebaseRecyclerOptions.Builder<AllUsersHelper>()
.setQuery(mDatabaseReference, AllUsersHelper.class)
.build();
firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<AllUsersHelper, UsersViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull final UsersViewHolder holder, int position, #NonNull AllUsersHelper model) {
holder.setName(model.getName());
holder.setStatus(model.getStatus());
holder.setImage(model.getImage());
final String userId = getRef(position).getKey();
mUsersDatabase.orderByChild("Name");
mUsersDatabase.child(userId).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String mName = dataSnapshot.child("Name").getValue().toString();
String mStatus = dataSnapshot.child("Status").getValue().toString();
String mDisplayImage = dataSnapshot.child("Image").getValue().toString();
if(dataSnapshot.hasChild("Online")) {
String userOnline = dataSnapshot.child("Online").getValue().toString();
holder.setUserOnline(userOnline);
}
holder.setName(mName);
holder.setImage(mDisplayImage);
holder.setStatus(mStatus);
mProgressDialogue.dismiss();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference().child("UserData").child(userId);
rootRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
userName = dataSnapshot.child("Name").getValue().toString();
Intent intent = new Intent(getActivity(), Chat.class);
intent.putExtra("Recievers_Id", userId);
intent.putExtra("Recievers_Name", userName);
startActivity(intent);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
});
}
#Override
public UsersViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.custom_activity_all_users, parent, false);
return new UsersViewHolder(view);
}
};
mUsersList.setAdapter(firebaseRecyclerAdapter);
return rootView;
}
public static class UsersViewHolder extends RecyclerView.ViewHolder {
public View mView;
public UsersViewHolder(View itemView) {
super(itemView);
mView = itemView;
}
public void setName(String name) {
TextView mDisplayName = (TextView) mView.findViewById(R.id.display_name);
mDisplayName.setText(name);
}
public void setStatus(String status) {
TextView mDisplayStatus = (TextView) mView.findViewById(R.id.display_status);
mDisplayStatus.setText(status);
}
public void setImage(String image) {
CircularImageView mDisplayImage = (CircularImageView) mView.findViewById(R.id.circleImageView);
Picasso.get().load(image).into(mDisplayImage);
}
public void setUserOnline(String userOnline) {
ImageView userOnlineView = (ImageView) mView.findViewById(R.id.online);
if(userOnline.equals("Online")){
userOnlineView.setVisibility(View.VISIBLE);
} else {
userOnlineView.setVisibility(View.INVISIBLE);
}
}
}
#Override
public void onStart() {
super.onStart();
firebaseRecyclerAdapter.startListening();
}
#Override
public void onStop() {
super.onStop();
if(firebaseRecyclerAdapter != null) {
firebaseRecyclerAdapter.stopListening();
}
}
}
Where should i put the keepSynced method for retrieving data offline because i tried below the database reference and it still doesn't show my data when i have no internet. Can someone help me out please... Also if the resukt is null how can i stop the progress dialog and show a text which says there are no users.
Right now you're just telling Firebase to keep an empty listener active on your Friends and UserData nodes. This ensures that the data from these nodes is always kept up to date (even when you don't attach any other listeners), but the data is still only kept in memory.
To persist the memory cache to disk, so that it can be reloaded in case you don't have an internet connection when starting the app, you'll need to call FirebaseDatabase.getInstance().setPersistenceEnabled(true) when the app starts. See enabling disk persistence in the Firebase docs.
Also see:
Firebase : What is the difference between setPersistenceEnabled and keepSynced?

Android - Firebase on data change refreshes the page

I'm kinda newbie to Android.
I have a recyclerview that I store in Firebase database.
My recyclerview are made of cardviews.
Inside each cardview I have a button that updates the node info in Firebase.
Each time the above is happening, my page refreshes (I guess to load the new data).
My mainactivity code relevant code(called on onCreate) :
private void loadRecyclerViewData() {
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (posts.size() > 0) {
posts.clear();
}
for (DataSnapshot ds : dataSnapshot.getChildren()) {
Post post = ds.getValue(Post.class);
//Getting a specific user's information (nickname purposes)
if (post.getSubGenreType().equals(SubGenreString)) {
posts.add(post);
Collections.reverse(posts);
}
}
adapter = new RecyclerAdapter(posts, getApplicationContext());
recyclerView.setAdapter(adapter);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
my adapter :
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
public static Boolean isAyed = false;
private FirebaseAuth firebaseAuth;
private List<Post> posts;
private Context context;
private String userTryToAyeEmail;
public RecyclerAdapter(List<Post> posts, Context context) {
this.posts = posts;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
firebaseAuth = FirebaseAuth.getInstance();
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recycle_card, parent, false);
return new ViewHolder(v);
}
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
final Post post = posts.get(position);
holder.imageButton.setVisibility(View.GONE);
holder.editText.setVisibility(View.GONE);
String colorString = post.getPostColor();
int color = Color.parseColor(colorString);
int newNumOfLikes = post.getPostLikes();
int currentNumOfLikes = post.getPostLikes();
// holder.cardView.setCardBackgroundColor(color);
holder.textViewHead.setText(post.getPostContent());
holder.textViewNickname.setText(post.getPostNickname());
holder.textViewTimeStamp.setText(post.getPostTimeStamp());
holder.ayeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Boolean userLiked = false;
if (firebaseAuth.getCurrentUser() != null) {
String currentUserEmail = firebaseAuth.getCurrentUser().getEmail();
List<String> currentLikedPost = post.getUserLikedList();
for (int i = 0; i < currentLikedPost.size(); i++) {
if (currentUserEmail.equals(currentLikedPost.get(i))) {
currentLikedPost.remove(i);
int newNumOfLikes = post.getPostLikes() - 1;
updateLikes(post.getId(), newNumOfLikes, post.getPostNickname(), post.getPostTimeStamp(), post.getPostContent(), post.getPostColor(), post.getSubGenreType(), post.getUserLikedList());
userLiked = true;
break;
}
}
if (!userLiked) {
currentLikedPost.add(currentUserEmail);
int newNumOfLikes = post.getPostLikes() + 1;
updateLikes(post.getId(), newNumOfLikes, post.getPostNickname(), post.getPostTimeStamp(), post.getPostContent(), post.getPostColor(), post.getSubGenreType(), post.getUserLikedList());
}
}
}
});
if (firebaseAuth.getCurrentUser() != null) {
String currentUserEmail = firebaseAuth.getCurrentUser().getEmail();
List<String> usersLikedPost = post.getUserLikedList();
for (int i = 0; i < usersLikedPost.size(); i++) {
if (currentUserEmail.equals(usersLikedPost.get(i))) {
holder.ayeButton.setTextColor(Color.parseColor("#FF0000"));
break;
}
}
}
holder.ayeTextView.setText(Integer.toString(newNumOfLikes));
holder.cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent myIntent = new Intent(context, SinglePostActivity.class);
myIntent.putExtra("postID", post.getId());
myIntent.putExtra("postNickname", post.getPostNickname());
myIntent.putExtra("postTimeStamp", post.getPostTimeStamp());
myIntent.putExtra("postContent", post.getPostContent());
myIntent.putExtra("postColor", post.getPostColor());
context.startActivity(myIntent);
}
});
}
private void updateLikes(String id, int newNumOfLikes, String postNickname, String postTimeStamp, String postContent, String postColor, String SubGenre, List<String> userLikedPostList) {
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("posts").child(id);
Post post = new Post(postColor, postContent, postNickname, postTimeStamp, id, newNumOfLikes, SubGenre, userLikedPostList);
databaseReference.setValue(post);
}
#Override
public int getItemCount() {
return posts.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView textViewHead;
public TextView textViewNickname;
public TextView textViewTimeStamp;
public TextView ayeButton;
public TextView ayeTextView;
public CardView cardView;
public LinearLayout linearLayout;
public EditText editText;
public ImageButton imageButton;
public ViewHolder(View itemView) {
super(itemView);
textViewHead = (TextView) itemView.findViewById(R.id.textViewHead);
textViewNickname = (TextView) itemView.findViewById(R.id.textViewNickname);
textViewTimeStamp = (TextView) itemView.findViewById(R.id.textViewTimeStamp);
ayeButton = (TextView) itemView.findViewById(R.id.ayeButton);
ayeTextView = (TextView) itemView.findViewById(R.id.ayeTextView);
cardView = (CardView) itemView.findViewById(R.id.cardViewID);
linearLayout = (LinearLayout) itemView.findViewById(R.id.cardLinearLayout);
editText = (EditText) itemView.findViewById(R.id.addCommentEditText);
imageButton = (ImageButton) itemView.findViewById(R.id.addCommentImageButton);
}
}
}
I wish the page to stay in place, how can I do that ??
Thank you all.
Set your adapter in onCreate and notify it from onDataChange
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_layout);
//initialize
.
.
//set adapter
adapter = new RecyclerAdapter(posts, getApplicationContext());
recyclerView.setAdapter(adapter);
}
private void loadRecyclerViewData() {
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (posts.size() > 0) {
posts.clear();
}
for (DataSnapshot ds : dataSnapshot.getChildren()) {
Post post = ds.getValue(Post.class);
//Getting a specific user's information (nickname purposes)
if (post.getSubGenreType().equals(SubGenreString)) {
posts.add(post);
Collections.reverse(posts);
}
}
adapter.notifyDataSetChanged(); //notify
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}

Sort data Decreasing - Firebase Query [duplicate]

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) { ....

How to set an icon for Cardview depending on a Firebase child String value?

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?

Categories

Resources