how to view user posts friends - Firestore - android

How could I view the posts, only from friends?
in this example I would like to display in RecyclerView only the posts of my friends. In this case the user 15. (certainly is several friends, I put only one to exemplify)
Structure - database:
USERS
-user01 (current user)
-name: John
-age: 20
--friends
----user10
----user15
-POSTS
--idpost_98685754
---user_post: user15
---title_post: Title
---photo: link
-posts
--idpost_41254d4554s1
---user_post: user40
---title_post: Title
---photo: link
-posts
--idpost_121221sss1
---user_post: user15
---title_post: Title 2
---photo: link 2
-posts
--idpost_9865565555
---user_post: user15
---title_post: Title 3
---photo: link 3
I currently use only the simple order and limit functions explained in the documentation. This is the first time I need to do something like that.
EDIT:
CODE - FRAGMENT:
/*Firebase*/
mDb = FirebaseFirestore.getInstance();
mQuery = mDb.collection("Posts");
Query mQueryNew = mQuery.orderBy("timestamp", Query.Direction.DESCENDING);
/* Recycler */
mCardFeedList = (RecyclerView) view.findViewById(id.cardFeedUser_list);
mCardFeedList.setHasFixedSize(true);
mCardFeedList.setItemViewCacheSize(20);
mCardFeedList.setDrawingCacheEnabled(true);
mAdapter = new PostsAdapter(mQueryNew, this){
#Override
protected void onDataChanged() {
if (getItemCount() == 0) {
mCardFeedList.setVisibility(View.GONE);
} else {
mCardFeedList.setVisibility(View.VISIBLE);
}
}
};
llmanager = new LinearLayoutManager(getActivity());
mCardFeedList.setLayoutManager(llmanager);
mCardFeedList.setAdapter(mAdapter);
/*START*/
if (mAdapter != null) {
mAdapter.startListening();
}
ADAPTER:
public class PostsAdapter extends FirestoreAdapter<PostsAdapter.ViewHolder> {
public interface OnPostsListner{
void onPostSelected(DocumentSnapshot post);
void onLikeSelected(DocumentSnapshot like);
void onCurtidasSelected(DocumentSnapshot curtidas);
void onFotoSelected(DocumentSnapshot foto);
void onCommentsSelected(DocumentSnapshot coments);
}
private OnPostsListner mListner;
public PostsAdapter (Query query, OnPostsListner listner){
super(query);
mListner = listner;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
return new ViewHolder(inflater.inflate(R.layout.card_feed_user_row, parent, false));
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.bind(getSnapshot(position), mListner);
}
static class ViewHolder extends RecyclerView.ViewHolder {
private Boolean mIsliked = false;
#BindView(R.id.tvCardFeedUser_nome)
TextView nomeUser;
#BindView(R.id.tvCardFeedUser_horario)
TextView horaFeed;
#BindView(R.id.tvCardFeedUser_desc)
TextView descFeed;
#BindView(R.id.ivCardFeedUser_image)
ImageView imageFeed;
#BindView(R.id.secaoLike)
LinearLayout curtir;
#BindView(R.id.secaoComments)
LinearLayout comentarios;
#BindView(R.id.tv_card_feed_linear_curtidas)
LinearLayout linear_curtidas;
#BindView(R.id.idBtnLike)
TextView btnLike;
#BindView(R.id.tv_card_feed_numero_curtidas)
TextView curtidas;
#BindView(R.id.tv_card_feed_nome_curtida)
TextView nome_curtidas;
public ViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
public void bind(final DocumentSnapshot snapshot,
final OnPostsListner listener) {
final Posts ref = snapshot.toObject(Posts.class);
FirebaseFirestore db = FirebaseFirestore.getInstance();
FirebaseAuth mAuth = FirebaseAuth.getInstance();
final FirebaseUser mCurrentUser = mAuth.getCurrentUser();
nomeUser.setText(ref.getNome_user());
descFeed.setText(ref.getDesc());
//Foto
Picasso.with(itemView.getContext()).load(ref.getImage()).placeholder(R.drawable.bck_padrao).networkPolicy(NetworkPolicy.OFFLINE).into(imageFeed, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
Picasso.with(itemView.getContext()).load(ref.getImage()).placeholder(R.drawable.bck_padrao).into(imageFeed);
}
});
SimpleDateFormat formatter = new SimpleDateFormat("dd/M/yy HH:mm");
String novaData = formatter.format(ref.getTimestamp());
horaFeed.setText(novaData);
/*CLICKS*/
curtir.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (listener != null) {
listener.onLikeSelected(snapshot);
}
}
});
imageFeed.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (listener != null) {
listener.onFotoSelected(snapshot);
}
}
});
comentarios.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (listener != null) {
listener.onCommentsSelected(snapshot);
}
}
});
linear_curtidas.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (listener != null) {
listener.onCurtidasSelected(snapshot);
}
}
});
// Click listener
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (listener != null) {
listener.onPostSelected(snapshot);
}
}
});
}
}
}

To achieve this, you need to query your database twice using nested query. First of all you need to query the database to get all the friends id that correspond to a single user and then based on those ids to query the database for the second time to display only the post de correspond to those particular friends.
One thing to note is that this cannot be done in a single query.

Related

Recyclerview won't show items, Firebase Admin SDK, Realtime Database

I'm trying to retrieve some simple data from my database as an Admin, the data has been retrieved, but nothing is shown on the recyclerview.
In the other hand, i was trying to assign a value (String) from the database to a TextView, i was recieving the value, but the TextView was empty, i went to the .xml file and changed the layout_width from android:layout_width="wrap_content" to android:layout_width="match_parent" and it worked! Before that with the simple Firebase Client SDK it was showing the texte even with android:layout_width="wrap_content"
PS: Since i started using the Firebase Admin SDK, I didn't had any issues with writing data to the Realtime database, Or with creating Users. I tried both of them and they works fine.
Here's the retrieving function :
private void RetriveClasses() {
// Get a reference to our posts
final FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("Classrooms");
mclassrooms.clear();
// Attach a listener to read the data at our posts reference
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren())
{
Classroom post = snapshot.getValue(Classroom.class);
if (!post.getDeleted().equals("true"))
{
mclassrooms.add(post);
}
mAdapter.notifyDataSetChanged();
System.out.println(post.getClassName());
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
System.out.println("The read failed: " + databaseError.getCode());
}
});
}
The System.out.println(post.getClassName()); Shows :
I/System.out: L1 ST 2022-2023
L1 ST 2021-2022
L1 ST 2015-2016
These are the class names i'm looking for, which means the reading is succeed, but the recyclerview still won't show any items.
here's my Adapter:
public class ClassroomsAdapter extends RecyclerView.Adapter<ClassroomsAdapter.ViewHolder> {
private Context c;
public List<Classroom> mclassrooms;
public ClassroomsAdapter(List<Classroom> mclassrooms) {
this.mclassrooms = mclassrooms;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
this.c = parent.getContext();
View view = LayoutInflater.from(c).inflate(R.layout.classroom_item, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
final Classroom classroom = mclassrooms.get(position);
if (classroom.getClassName().length() >= 20)
{
String className = classroom.getClassName();
holder.classroom_name.setText(className.substring(0,19) + "...");
}
else
{
holder.classroom_name.setText(classroom.getClassName());
}
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
final BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(c, R.style.BottomSheetDialogTheme);
View eview = LayoutInflater.from(c).inflate(R.layout.bottom_menu_classroom, null);
eview.findViewById(R.id.Delete_Comment_Btn).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final ProgressDialog progressDialog = new ProgressDialog(c, R.style.MyAlertDialogStyle);
progressDialog.setTitle("Suppression");
progressDialog.setMessage("Traitement...");
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.show();
DatabaseReference mRoot = FirebaseDatabase.getInstance().getReference("Classrooms");
mRoot.child(classroom.getClassId()).child("deleted").setValue("true", new DatabaseReference.CompletionListener(){
#Override
public void onComplete(DatabaseError error, DatabaseReference ref) {
progressDialog.dismiss();
Toast.makeText(c, "Suppression avec succès!", Toast.LENGTH_SHORT).show();
bottomSheetDialog.dismiss();
}
});
}
});
eview.findViewById(R.id.copy_comment_button).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final BottomSheetDialog bs = new BottomSheetDialog(c, R.style.BottomSheetDialogTheme);
View aview = LayoutInflater.from(c).inflate(R.layout.edit_class_name, null);
EditText name_et = aview.findViewById(R.id.Edition_Comment_Input_Field);
name_et.setText(classroom.getClassName());
aview.findViewById(R.id.update_comment).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (name_et.getText().toString().isEmpty()) {
Toast.makeText(c, "Ce champ est requis*", Toast.LENGTH_SHORT).show();
} else {
final ProgressDialog progressDialog = new ProgressDialog(c, R.style.MyAlertDialogStyle);
progressDialog.setTitle("Mise à jour");
progressDialog.setMessage("Traitement...");
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.show();
DatabaseReference mRoot = FirebaseDatabase.getInstance().getReference("Classrooms");
mRoot.child(classroom.getClassId()).child("className").setValue(name_et.getText().toString(), new DatabaseReference.CompletionListener() {
#Override
public void onComplete(DatabaseError error, DatabaseReference ref) {
progressDialog.dismiss();
Toast.makeText(c, "Mise à jour avec succès!", Toast.LENGTH_SHORT).show();
bs.dismiss();
bottomSheetDialog.dismiss();
}
});
}
}
});
aview.findViewById(R.id.close_edit_comment).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
bs.dismiss();
}
});
bs.setContentView(aview);
bs.show();
}
});
bottomSheetDialog.setContentView(eview);
bottomSheetDialog.show();
return false;
}
});
}
#Override
public int getItemCount() {
return mclassrooms.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView classroom_name;
public ViewHolder(#NonNull View itemView) {
super(itemView);
classroom_name = itemView.findViewById(R.id.class_name);
}
}
}
Thanks for your time.

Removing all items from recyclerview at ONCE on firebase ui

I can delete one at a time in the recyclerview but trying to figure out how to delete the entire element at ONCE in the recyclerview when the finished button is clicked. this is my first time making use of this platform to ask question. Please can someone assist me on this code, i try so many times to remove all items at ONCE from the recyclerview in firebase UI and get error or no results at all. please how to fix this kind of issue and here is my code below. enter image description here
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cart);
mCartTotal = findViewById(R.id.TV_ShoppingCart_Total);
mBtnFinish = findViewById(R.id.LinearLayout_Cart_Next_Address);
mShopping_RecyclerView = findViewById(R.id.recycler_view_shopping_cart);
mShopping_RecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
mShopping_RecyclerView.setHasFixedSize(false);
mBtnFinish.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Please what should i put in here
Intent navigateShippingScreen = new Intent(CartActivity.this, ShippingAddressActivity.class);
navigateShippingScreen.putExtra("Total Price", String.valueOf(overAllTotalPrice));
startActivity(navigateShippingScreen);
finish();
}
});
readDataCart();
}
private void readDataCart() {
FirebaseUser AppUser = FirebaseAuth.getInstance().getCurrentUser();
if (AppUser != null) {
USER_ID = FirebaseAuth.getInstance().getCurrentUser().getUid();
CART_PRODUCT = FirebaseAuth.getInstance().getCurrentUser().getUid();
Query query = FirebaseFirestore.getInstance()
.collection("REGISTERED USERS").document(USER_ID)
.collection("CART PRODUCT").orderBy("productTime", Query.Direction.ASCENDING);
options = new FirestoreRecyclerOptions.Builder<PharmacyCart_DataModel>()
.setQuery(query, PharmacyCart_DataModel.class)
.build();
myAdapter = new FirestoreRecyclerAdapter<PharmacyCart_DataModel, myViewHolderCart>(options) {
#SuppressLint("SetTextI18n")
#Override
protected void onBindViewHolder(#NonNull myViewHolderCart holder, int position, #NonNull PharmacyCart_DataModel model) {
holder.mCartTitle.setText(model.getProductCartName());
holder.mCartPrice.setText("RM" + model.getProductCartPrice());
holder.mCartQuantity.setText(model.getProductCartQuantity());
int oneTypeProductPrice = Integer.valueOf(model.getProductCartPrice()) * Integer.valueOf(model.getProductCartQuantity());
overAllTotalPrice = overAllTotalPrice + oneTypeProductPrice;
mCartTotal.setText("RM " + String.valueOf(overAllTotalPrice));
holder.mDeleteProductCart.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
_deleteCartItemNow(holder);
int oneTypeProductPrice = Integer.valueOf(model.getProductCartPrice()) * Integer.valueOf(model.getProductCartQuantity());
overAllTotalPrice = overAllTotalPrice - oneTypeProductPrice;
mCartTotal.setText("RM " + String.valueOf(overAllTotalPrice));
}
});
}
#NonNull
#Override
public myViewHolderCart onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_cart_product, parent, false);
return new myViewHolderCart(v);
}
};
mShopping_RecyclerView.setAdapter(myAdapter);
}
}
private void _deleteCartItemNow(myViewHolderCart holder) {
_deleteCartItem(holder.getAdapterPosition());
}
private void _deleteCartItem(int position) {
myAdapter.getSnapshots().getSnapshot(position).getReference().delete();
}
#Override
protected void onStart() {
super.onStart();
myAdapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
myAdapter.stopListening();
}

load image and video in recylerview

I have an adapter class where I am able to load all video from Firebase. But the problem is I can't load both, image and video in one RecyclerView
See what I have done:
I am using toro library to auto play video if your wondering and ExoPlayer to play video
This is my adapter class
public class MainFeedAdapter extends RecyclerView.Adapter<TestAdapter.MyViewHolder> {
private static final String TAG = "MainfeedAdapter";
private List<Photo> moviesList;
private DatabaseReference mReference;
private Context mContext;
private String currentUsername = "";
private int mLayoutResource;
private LayoutInflater mInflater;
private Photo photo;
private MyViewHolder mHolder;
public class MyViewHolder extends RecyclerView.ViewHolder implements ToroPlayer{
static final int LAYOUT_RES = R.layout.main_list;
private ExoPlayerViewHelper helper;
private CircleImageView profile_image;
//private String likeString;
private TextView username,time,caption,likes,comment,stars;
private SquareImageView image;
private LikeButton mHeart,Star;
private UserAccountSettings userAccountSettings = new UserAccountSettings();
private User user = new User();
private StringBuilder users;
private String mLIkeString;
private String mStarString;
private boolean likeByCurrentUSer;
private boolean starbycurrentuser;
private DatabaseReference mNotification;
private ImageView commentBubble;
private Uri mediaUri;
#BindView(R.id.main_post_image2)
PlayerView playerView;
private CardView video;
public MyViewHolder(View view) {
super(view);
profile_image = (CircleImageView)view.findViewById(R.id.post_profile_photo);
username = (TextView) view.findViewById(R.id.main_username);
time = (TextView) view.findViewById(R.id.main_image_time_posted);
caption = (TextView) view.findViewById(R.id.main_image_caption);
likes = (TextView) view.findViewById(R.id.main_likes);
comment = (TextView) view.findViewById(R.id.main_showcomments);
image = (SquareImageView) view.findViewById(R.id.main_post_image);
mHeart = (LikeButton) view.findViewById(R.id.main_heart);
Star = (LikeButton) view.findViewById(R.id.main_star);
stars= (TextView)view.findViewById(R.id.stars);
commentBubble = (ImageView)view.findViewById(R.id.main_comments) ;
mNotification = FirebaseDatabase.getInstance().getReference().child("notification");
mReference = FirebaseDatabase.getInstance().getReference();
ButterKnife.bind(this, itemView);
video = (CardView)view.findViewById(R.id.video_posts);
}
#NonNull
#Override
public View getPlayerView() {
return playerView;
}
#NonNull
#Override
public PlaybackInfo getCurrentPlaybackInfo() {
return helper != null ? helper.getLatestPlaybackInfo() : new PlaybackInfo();
}
#Override
public void initialize(#NonNull Container container, #Nullable PlaybackInfo playbackInfo) {
if (helper == null) {
helper = new SimpleExoPlayerViewHelper(container, this, mediaUri);
}
helper.initialize(playbackInfo);
}
// called from Adapter to setup the media
void bind( Uri item, List<Photo> payloads) {
if (item != null) {
mediaUri = item;
}else {
video.setVisibility(View.GONE);
}
}
#Override
public void play() {
if (helper != null) helper.play();
}
#Override
public void pause() {
if (helper != null) helper.pause();
}
#Override
public boolean isPlaying() {
return helper != null && helper.isPlaying();
}
#Override
public void release() {
if (helper != null) {
helper.release();
helper = null;
}
}
#Override
public boolean wantsToPlay() {
return ToroUtil.visibleAreaOffset(this, itemView.getParent()) >= 0.85;
}
#Override
public int getPlayerOrder() {
return getAdapterPosition();
}
#Override
public void onSettled(Container container) {
}
}
public TestAdapter(List<Photo> moviesList) {
this.moviesList = moviesList;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.main_list, parent, false);
mContext = parent.getContext();
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
photo = moviesList.get(position);
mHolder = holder;
holder.users = new StringBuilder();
getCurrentUsername();
getLikesString(mHolder);
getStarString(mHolder);
holder.bind(Uri.parse(photo.getVideo_path()),moviesList);
//get the profile image and username
DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
Query query = reference
.child(mContext.getString(R.string.dbname_user_account_settings))
.orderByChild(mContext.getString(R.string.field_user_id))
.equalTo(getItem(position).getUser_id());
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot singleSnapshot : dataSnapshot.getChildren()){
// currentUsername = singleSnapshot.getValue(UserAccountSettings.class).getUsername();
Log.d(TAG, "onDataChange: found user: "
+ singleSnapshot.getValue(UserAccountSettings.class).getUsername());
holder.username.setText(singleSnapshot.getValue(UserAccountSettings.class).getUsername());
holder.username.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "onClick: navigating to profile of: " +
holder.user.getUsername());
Intent intent = new Intent(mContext, Profile_Activity.class);
intent.putExtra(mContext.getString(R.string.calling_activity),
mContext.getString(R.string.home_activity));
intent.putExtra(mContext.getString(R.string.intent_user), holder.user);
mContext.startActivity(intent);
}
});
imageLoader.displayImage(singleSnapshot.getValue(UserAccountSettings.class).getProfile_photo(),
holder.profile_image);
holder.profile_image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "onClick: navigating to profile of: " +
holder.user.getUsername());
Intent intent = new Intent(mContext, Profile_Activity.class);
intent.putExtra(mContext.getString(R.string.calling_activity),
mContext.getString(R.string.home_activity));
intent.putExtra(mContext.getString(R.string.intent_user), holder.user);
mContext.startActivity(intent);
}
});
holder.userAccountSettings = singleSnapshot.getValue(UserAccountSettings.class);
holder.comment.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((HomeActivity)mContext).onCommentThreadSelected(getItem(position),mContext.getString(R.string.home_activity));
//another thing?
((HomeActivity)mContext).hideLayout();
}
});
holder.commentBubble.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((HomeActivity)mContext).onCommentThreadSelected(getItem(position),mContext.getString(R.string.home_activity));
//another thing?
((HomeActivity)mContext).hideLayout();
}
});
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Query userQuery = mReference
.child(mContext.getString(R.string.dbname_users))
.orderByChild(mContext.getString(R.string.field_user_id))
.equalTo(getItem(position).getUser_id());
userQuery.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot singleSnapshot : dataSnapshot.getChildren()){
Log.d(TAG, "onDataChange: found user: " +
singleSnapshot.getValue(User.class).getUsername());
holder.user = singleSnapshot.getValue(User.class);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private boolean rechedendoflist(int position){
return position == getItemCount() -1;\
}
#Override
public int getItemCount() {
return moviesList.size();
}
public Photo getItem(int position) {
return moviesList.get(position);
}
private void getCurrentUsername(){
Log.d(TAG, "getCurrentUser: ");
Log.d(TAG, "getCurrentUsername: retrieving user account settings");
DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
Query query = reference
.child(mContext.getString(R.string.dbname_users))
.orderByChild(mContext.getString(R.string.field_user_id))
.equalTo(FirebaseAuth.getInstance().getCurrentUser().getUid());
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot singleSnapshot : dataSnapshot.getChildren()){
currentUsername = singleSnapshot.getValue(UserAccountSettings.class).getUsername();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
Please help me guys!. Thanks in Advance!.
TheRecyclerView has ability to show items in multiple types.
In your case you can define two ViewType. one for Images and another for Videos.
Search about RecyclerView with multiple view types.
Take a look at here and this.
Also here is a question and answers about it.

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) {
}
});
}

How to load batches of data in a recycler view using firestore?

I wanted to know how to load more data in recylcer view using firestore.
Query query = FirebaseFirestore.getInstance()
.collection("ie").limit(5);
adapter=new InterviewAdapter(this,query);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
Adapter class looks like this:
public class InterviewAdapter extends FireStoreAdapter<InterviewAdapter.ViewHolder> {
public interface OnInterviewSelectedListener {
void onInterviewSelected(DocumentSnapshot interview);
}
private InterviewAdapter.OnInterviewSelectedListener mListener;
public InterviewAdapter(Query query, OnInterviewSelectedListener listener) {
super(query);
mListener = listener;
}
#Override
public InterviewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
return new InterviewAdapter.ViewHolder(inflater.inflate(R.layout.ie, parent, false));
}
#Override
public void onBindViewHolder(InterviewAdapter.ViewHolder holder, int position) {
holder.bind(getSnapshot(position), mListener);
}
static class ViewHolder extends RecyclerView.ViewHolder {
TextView title,companyName,username,views,isHired;
public ViewHolder(View itemView) {
super(itemView);
title= (TextView) itemView.findViewById(R.id.title);
companyName= (TextView) itemView.findViewById(R.id.companyName);
username= (TextView) itemView.findViewById(R.id.username);
views= (TextView) itemView.findViewById(R.id.views);
isHired= (TextView) itemView.findViewById(R.id.isHired);
}
public void bind(final DocumentSnapshot snapshot,
final OnInterviewSelectedListener listener) {
InterviewExperience experience;
String companyName=snapshot.getString("companyName");
boolean isHired=Boolean.valueOf(snapshot.getBoolean("isHired"));
String username=snapshot.getString("username");
long views=new Double(Double.valueOf(snapshot.getDouble("views"))).longValue();
String id=snapshot.getId();
String title=snapshot.getString("title");
experience=new InterviewExperience(id,title,companyName,username,isHired,views,null,null);
this.title.setText(experience.getTitle());
this.companyName.setText("Company Name: "+experience.getCompanyName());
this.isHired.setText("Hired: "+experience.isHired());
this.views.setText("Views: "+experience.getViews()+"");
this.username.setText("Created By: "+experience.getUsername());
// Click listener
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (listener != null) {
listener.onInterviewSelected(snapshot);
}
}
});
}
}
}
public abstract class FireStoreAdapter<VH extends RecyclerView.ViewHolder>
extends RecyclerView.Adapter<VH>
implements EventListener<QuerySnapshot> {
private static final String TAG = "FirestoreAdapter";
private Query mQuery;
private ListenerRegistration mRegistration;
private ArrayList<DocumentSnapshot> mSnapshots = new ArrayList<>();
public FireStoreAdapter(Query query) {
mQuery = query;
}
#Override
public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) {
if (e != null) {
Log.w(TAG, "onEvent:error", e);
onError(e);
return;
}
// Dispatch the event
Log.d(TAG, "onEvent:numChanges:" + documentSnapshots.getDocumentChanges().size());
for (DocumentChange change : documentSnapshots.getDocumentChanges()) {
switch (change.getType()) {
case ADDED:
onDocumentAdded(change);
break;
case MODIFIED:
onDocumentModified(change);
break;
case REMOVED:
onDocumentRemoved(change);
break;
}
}
onDataChanged();
}
public void startListening() {
if (mQuery != null && mRegistration == null) {
mRegistration = mQuery.addSnapshotListener(this);
}
}
public void stopListening() {
if (mRegistration != null) {
mRegistration.remove();
mRegistration = null;
}
mSnapshots.clear();
notifyDataSetChanged();
}
public void setQuery(Query query) {
// Stop listening
stopListening();
// Clear existing data
mSnapshots.clear();
notifyDataSetChanged();
// Listen to new query
mQuery = query;
startListening();
}
#Override
public int getItemCount() {
return mSnapshots.size();
}
protected DocumentSnapshot getSnapshot(int index) {
return mSnapshots.get(index);
}
protected void onDocumentAdded(DocumentChange change) {
mSnapshots.add(change.getNewIndex(), change.getDocument());
notifyItemInserted(change.getNewIndex());
}
protected void onDocumentModified(DocumentChange change) {
if (change.getOldIndex() == change.getNewIndex()) {
// Item changed but remained in same position
mSnapshots.set(change.getOldIndex(), change.getDocument());
notifyItemChanged(change.getOldIndex());
} else {
// Item changed and changed position
mSnapshots.remove(change.getOldIndex());
mSnapshots.add(change.getNewIndex(), change.getDocument());
notifyItemMoved(change.getOldIndex(), change.getNewIndex());
}
}
protected void onDocumentRemoved(DocumentChange change) {
mSnapshots.remove(change.getOldIndex());
notifyItemRemoved(change.getOldIndex());
}
protected void onError(FirebaseFirestoreException e) {};
protected void onDataChanged() {}
}
I used Firestore Adapter code which was given in samples of firestore documentation. Can anyone tell how to use the query object to load more data?
How to load the next 5 items in the recycler view when users scrolls to the end of the list?
You can paginate your Query's result using Query's methods like, startAt(), startAfter(), endAt(), endBefore() with a specified DocumentSnapshot.
If I considered your collection is called "interviews", you can add a method to your FireStoreAdapter like this:
private void paginate(final DocumentSnapshot last, final int limit) {
final Query subset;
if (last == null) {
subset = db.collection("interviews")
.limit(limit);
} else {
subset = db.collection("interviews")
.startAfter(last)
.limit(limit);
}
setQuery(subset);
}
You can perserve the last DocumentSnapshot within onEvent():
final List<DocumentChange> changes = documentSnapshots.getDocumentChanges();
final DocumentSnapshot lastDocument = changes.get(changes.size() - 1).getDocument();
Finally, when users scrolls to the end of the list:
paginate(lastDocument, 5);
And onDocumentAdded() will take care of it. Be carfure NOT to use startAt() because it will not execlude the last one (that already at the end of your list, and will duplicate it).

Categories

Resources