SwipeRefreshLayout refreshes RecyclerView without having to pull down - java

I am trying to implement an SwipeRefreshLayout into my app. What I want to happen is that when the user opens the app initially that the data is retrieved from Firebase without having to pull down the layout so the data refreshes. After that, if the user wants to see new data they have to pull down the layout so the RecyclerView is refreshed with new posts that other users have uploaded.
The problem that I am running into is that when I upload a post from my emulator it pops up on screen automatically on my phone without me having to pull down. That's not what I want. First, initial opening of app data should be retrieved automatically without pull down. After that, every time you want to see new data, if I go to a different fragment and then come back the data shouldn't be refreshed unless I pull down.
The code that I have currently is the following. Can someone tell me why it isn't working the way that I would like it to?
I am relatively sure that it's because of my notifyDataSetChanged(); in my readPosts(); method, but I'm not sure how to fix it... Should I just remove it from readPosts(); and add it to the mSwipeRefreshLayout.post...Runnable?
HomeFragment
public class HomeTabLayoutFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
private ProgressBar mProgressBar;
private PostAdapter mPostAdapter;
private List<Post> mPostLists;
private FirebaseAuth mFirebaseAuth;
private FirebaseUser mFirebaseUser;
private List<String> mFollowingList;
private SwipeRefreshLayout mSwipeRefreshLayout;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_home_tab_layout, container, false);
mFirebaseAuth = FirebaseAuth.getInstance();
mFirebaseUser = FirebaseAuth.getInstance().getCurrentUser();
mProgressBar = v.findViewById(R.id.progress_circular);
RecyclerView recyclerView = v.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
linearLayoutManager.setReverseLayout(true);
linearLayoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(linearLayoutManager);
mPostLists = new ArrayList<>();
mPostAdapter = new PostAdapter(getContext(), mPostLists);
recyclerView.setAdapter(mPostAdapter);
mSwipeRefreshLayout = v.findViewById(R.id.refresh);
mSwipeRefreshLayout.setOnRefreshListener(this);
mSwipeRefreshLayout.post(() -> {
mSwipeRefreshLayout.setRefreshing(true);
readPosts();
});
checkIfUserExists();
checkFollowing();
return v;
}
#Override
public void onRefresh() {
readPosts();
}
private void checkIfUserExists() {
if (mFirebaseAuth == null) {
Intent intent = new Intent(getContext(), RegisterActivity.class);
startActivity(intent);
}
}
private void checkFollowing() {
mFollowingList = new ArrayList<>();
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Follow").child(mFirebaseUser.getUid()).child("Following");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
mFollowingList.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
mFollowingList.add(snapshot.getKey());
}
readPosts();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
private void readPosts() {
mSwipeRefreshLayout.setRefreshing(true);
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Posts");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
mPostLists.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
Post post = snapshot.getValue(Post.class);
if (post != null && shouldAddPost(post)) {
mPostLists.add(post);
}
}
mPostAdapter.notifyDataSetChanged();
mProgressBar.setVisibility(View.GONE);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
mSwipeRefreshLayout.setRefreshing(false);
}
private boolean shouldAddPost(#NotNull Post post) {
boolean isFollowingPublisher = false;
for (String id : mFollowingList) {
if (post.getPublisher().equals(id)) {
isFollowingPublisher = true;
break;
}
}
boolean isPublisher = post.getPublisher().equals(mFirebaseUser.getUid());
return isFollowingPublisher || isPublisher;
}
}

That is because you are using a addValueEventListener. In this case a ValueEventListener will get called each time any changes made in this hierarchy.
You should be using addListenerForSingleValueEvent if you want data only once. In other words if you do not want realtime updates for a node then you use addListenerForSingleValueEvent.
->Answer about mSwipeRefreshLayout.setRefreshing(false) positioning inside readPost .
Right now how you added mSwipeRefreshLayout.setRefreshing(true) and mSwipeRefreshLayout.setRefreshing(false) is actually useless . It will call immediately.. What you should be doing is changing the state inside listeners.
private void readPosts() {
mSwipeRefreshLayout.setRefreshing(true);
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Posts");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
mPostLists.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
Post post = snapshot.getValue(Post.class);
if (post != null && shouldAddPost(post)) {
mPostLists.add(post);
}
}
mPostAdapter.notifyDataSetChanged();
mProgressBar.setVisibility(View.GONE);
mSwipeRefreshLayout.setRefreshing(false);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
mSwipeRefreshLayout.setRefreshing(false);
}
});

Related

Chat app - update token chat fragment - new version

I'm creating a chat app and I imported this 3-year-old project so a lot of things have changed, especially this thing that I can't fix could anyone help me? Thanks.
The error that gives me:
'updateToken(java.lang.String)' in 'com.koddev.chatapp.Fragments.ChatsFragment' cannot be applied to '(com.google.android.gms.tasks.Task<java.lang.String>)'
public class ChatsFragment extends Fragment {
private RecyclerView recyclerView;
private UserAdapter userAdapter;
private List<User> mUsers;
FirebaseUser fuser;
DatabaseReference reference;
private List<Chatlist> usersList;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_chats, container, false);
recyclerView = view.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
fuser = FirebaseAuth.getInstance().getCurrentUser();
usersList = new ArrayList<>();
reference = FirebaseDatabase.getInstance().getReference("Chatlist").child(fuser.getUid());
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
usersList.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()){
Chatlist chatlist = snapshot.getValue(Chatlist.class);
usersList.add(chatlist);
}
chatList();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
updateToken(FirebaseMessaging.getInstance().getToken());
return view;
}
private void updateToken(String token){
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Tokens");
Token token1 = new Token(token);
reference.child(fuser.getUid()).setValue(token1);
}
private void chatList() {
mUsers = new ArrayList<>();
reference = FirebaseDatabase.getInstance().getReference("Users");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
mUsers.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()){
User user = snapshot.getValue(User.class);
for (Chatlist chatlist : usersList){
if (user.getId().equals(chatlist.getId())){
mUsers.add(user);
}
}
}
userAdapter = new UserAdapter(getContext(), mUsers, true);
recyclerView.setAdapter(userAdapter);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
You're getting the following error:
'updateToken(java.lang.String)' in 'com.koddev.chatapp.Fragments.ChatsFragment' cannot be applied to '(com.google.android.gms.tasks.Task<java.lang.String>)'
Because you're calling the updateToken() method with a wrong argument. You defined the method to take a String argument, while you're calling it with a Task object, hence the error. If you want to get the token and call the method correctly, please use the following lines of code:
FirebaseMessaging.getInstance().getToken().addOnCompleteListener(new OnCompleteListener<String>() {
#Override
public void onComplete(#NonNull Task<String> task) {
if (task.isSuccessful()) {
String token = task.getResult();
updateToken(token);
Log.d("TAG", token); //Check the generated token.
} else {
Log.d("TAG", task.getException().getMessage()); //Never ignore potential errors!
}
}
});

Firebase database set objects in favorite list

I have a problem clearing list in fragments. I need to clear the list when happening update in fragment. I already put it in different places but it does not help me.
When an update happens in fragment it shows the same list but that list also add elements from the previous list. If I put list.clear(); in the moment when it rakes arguments from firebase it did not give me needed effect, when I put it in onCreate() method then app gives me error.
public class Favourite extends Fragment {
private RecyclerView recyclerView;
private ArrayList<TourReader1> artistList;
private ToursAdapter1 adapter1;
private DatabaseReference reference,reference2;
String uid;
public Favourite() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
//Get current user id
uid = user.getUid();
//Connect to specific point in database Tours
reference = FirebaseDatabase.getInstance().getReference("Tours");
//Create add to method valuelistener or reference which is specific point in database
reference2 = FirebaseDatabase.getInstance().getReference("user").child(uid);
reference.addValueEventListener(valueEventListener);
reference.keepSynced(true);
}
ValueEventListener valueEventListener = (new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot1) {
//get all information from specific point of database
for (DataSnapshot datasnapshot : snapshot1.getChildren()) {
//get current name of starting point from where we recive information from database
String firstname = datasnapshot.getKey();
//valuelistener for another point from database
reference2.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot dSnapshot2:snapshot.getChildren()){
String seconame = dSnapshot2.getKey();
Boolean control = dSnapshot2.child("like").getValue(Boolean.class);
if(control != null&&firstname.equals(seconame) &&control.equals(true)) {
TourReader1 artist = datasnapshot.getValue(TourReader1.class);
artistList.add(artist);
}
}
adapter1.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
artistList = new ArrayList<>();
View rootview = inflater.inflate(R.layout.favourite, container, false);
recyclerView = rootview.findViewById(R.id.list);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
adapter1 = new ToursAdapter1(getContext(), artistList);
recyclerView.setAdapter(adapter1);
GridLayoutManager mGridLayoutManager = new GridLayoutManager(getContext(), 2);
recyclerView.setLayoutManager(mGridLayoutManager);
return rootview;
}
}
You should clear the artistList using artistList.clear() before your for loop in onDataChangeas this list is having the data from the last callback triggered.
Ok, I found the answer myself, I clear my list in the adapter by tourlist.clear() and remove userpoints.keepSynced(true); when like icon is false.
holder.sparkButton.setEventListener(new SparkEventListener() {
#Override
public void onEvent(ImageView button, boolean buttonState) {
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
String uid = user.getUid();
DatabaseReference userpoints = FirebaseDatabase.getInstance().getReference("user").child(uid);
ToursLike registerDatabase = new ToursLike(true);
if(buttonState){
userpoints.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (!dataSnapshot.hasChild(tour.Name)) {
userpoints.child(tour.Name).setValue(registerDatabase);
userpoints.keepSynced(true);
tourList.clear();
}
else{
userpoints.child(tour.Name).child("like").setValue(true);
userpoints.keepSynced(true);
tourList.clear();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
else{
userpoints.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
userpoints.child(tour.Name).child("like").setValue(false);
tourList.clear();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
#Override
public void onEventAnimationEnd(ImageView button, boolean buttonState) {
}
#Override
public void onEventAnimationStart(ImageView button, boolean buttonState) {
}
});
}

Posts on newsfeed are coming out duplicated if it's your profile, posts of other users are coming out just once

I have the following problem. Posts of other users are coming out fine only one post. But if it's your profile, in the HomeFragment the posts are coming out duplicated and I am not sure why that is.
In my readPosts(); method, if I get rid of this line } else if (mFirebaseUser.getUid().equals(post.getPublisher())) {mPostLists.add(post); it's fine, but then my posts don't show up only the posts of the people I follow. I need mine to show up also in the newsfeed, but just once not duplicated. All of my posts are being duplicated. Same post comes up twice on my feed. Can someone tell me what I am doing wrong?
Something I am doing wrong in my readPosts(); method, but I am not sure what after having played around with it a bunch.
HomeFragment
public class HomeTabLayoutFragment extends Fragment {
private ProgressBar mProgressBar;
private PostAdapter mPostAdapter;
private List<Post> mPostLists;
private FirebaseAuth mFirebaseAuth;
private FirebaseUser mFirebaseUser;
private List<String> mFollowingList;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_home_tab_layout, container, false);
mFirebaseAuth = FirebaseAuth.getInstance();
mFirebaseUser = FirebaseAuth.getInstance().getCurrentUser();
mProgressBar = v.findViewById(R.id.progress_circular);
RecyclerView recyclerView = v.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
linearLayoutManager.setReverseLayout(true);
linearLayoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(linearLayoutManager);
mPostLists = new ArrayList<>();
mPostAdapter = new PostAdapter(getContext(), mPostLists);
recyclerView.setAdapter(mPostAdapter);
SwipeRefreshLayout refreshLayout = v.findViewById(R.id.refresh);
refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
refreshLayout.setRefreshing(false);
}
});
checkIfUserExists();
checkFollowing();
return v;
}
private void checkIfUserExists() {
if (mFirebaseAuth == null) {
Intent intent = new Intent(getContext(), RegisterActivity.class);
startActivity(intent);
}
}
private void checkFollowing() {
mFollowingList = new ArrayList<>();
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Follow").child(mFirebaseAuth.getCurrentUser().getUid()).child("Following");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
mFollowingList.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
mFollowingList.add(snapshot.getKey());
}
readPosts();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
private void readPosts() {
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Posts");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
mPostLists.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
Post post = snapshot.getValue(Post.class);
for (String id : mFollowingList) {
if (post != null) {
if (post.getPublisher().equals(id)) {
mPostLists.add(post);
} else if (mFirebaseUser.getUid().equals(post.getPublisher())) {
mPostLists.add(post);
}
}
}
mPostAdapter.notifyDataSetChanged();
mProgressBar.setVisibility(View.GONE);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
Check your inner loop in readPosts(). The loop is based on elements of mFollowingList. This condition has nothing to do with that:
if (mFirebaseUser.getUid().equals(post.getPublisher()))
It will be either true or false for every execution of the internal loop. Therefore, it may add more elements than you want. You probably want to put it in the outer loop, not the inner one - to execute it just once per post.
I'd make some more changes though. The check (post != null) can be done outside the loop. No need to let it loop multiple times for no reason. notifyDataSetChanged() also does not need to be inside any loop, it needs to be called once.
Extra regarding code style :-) - You're using too much indentation. It makes sense to extract things to a separate method for readability, it's a good idea to keep methods short, with descriptive names.
private void readPosts() {
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Posts");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
mPostLists.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
Post post = snapshot.getValue(Post.class);
if (post != null && shouldAddPost(post)) {
mPostLists.add(post);
}
}
mPostAdapter.notifyDataSetChanged();
mProgressBar.setVisibility(View.GONE);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
private boolean shouldAddPost(#NotNull Post post) {
boolean isFollowingPublisher = false;
for (String id : mFollowingList) {
if (post.getPublisher().equals(id)) {
isFollowingPublisher = true;
}
}
boolean isPublisher = post.getPublisher().equals(mFirebaseUser.getUid());
return isFollowingPublisher || isPublisher;
}
private void readPosts() {
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Posts");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
mPostLists.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
Post post = snapshot.getValue(Post.class);
for (String id : mFollowingList) {
if (post != null) {
if (post.getPublisher().equals(id)) {
mPostLists.add(post);
}
}
}
if (post != null)
if (mFirebaseUser.getUid().equals(post.getPublisher())) {
mPostLists.add(post);
}
}
mPostAdapter.notifyDataSetChanged();
mProgressBar.setVisibility(View.GONE);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}

I get a No view for id for fragment

I am trying to have an activity inside of my fragment, the fragment shows posts of people you follow and the activity shows the most recent post from anyone.
My fragment..
public class HomeFragment extends Fragment {
private PostAdapter postAdapter;
private List<Post> postLists;
private List<String> followingList;
private ProgressBar progressBar;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.fragment_home, container,false);
RecyclerView recyclerView = view.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager=new LinearLayoutManager(getContext());
linearLayoutManager.setReverseLayout(true);
linearLayoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(linearLayoutManager);
postLists=new ArrayList<>();
postAdapter=new PostAdapter(getContext(), postLists);
recyclerView.setAdapter(postAdapter);
ImageView globalPosts = view.findViewById(R.id.globalPosts);
globalPosts.setOnClickListener(v->{
Intent intent= new Intent(getContext(), GlobalPostsActivity.class);
startActivity(intent);
});
progressBar=view.findViewById(R.id.progress_circular);
checkFollowing();
return view;
}
private void checkFollowing(){
followingList=new ArrayList<>();
DatabaseReference reference=FirebaseDatabase.getInstance().getReference("Support")
.child(Objects.requireNonNull(FirebaseAuth.getInstance().getCurrentUser()).getUid())
.child("supporting");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
followingList.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()){
followingList.add(snapshot.getKey());
}
readPosts();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
private void readPosts(){
DatabaseReference reference= FirebaseDatabase.getInstance().getReference("Posts");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
postLists.clear();
for (DataSnapshot snapshot :dataSnapshot.getChildren()){
Post post=snapshot.getValue(Post.class);
for (String id: followingList){
assert post != null;
if (post.getPublisher().equals(id)){
postLists.add(post);
}
}
}
postAdapter.notifyDataSetChanged();
progressBar.setVisibility(View.GONE);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
My activity..
public class GlobalPostsActivity extends AppCompatActivity {
private PostAdapter postAdapter;
private List<Post> postLists;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_global_posts);
RecyclerView recyclerView = findViewById(R.id.recycler_view1);
recyclerView.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getApplicationContext());
linearLayoutManager.setReverseLayout(true);
linearLayoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(linearLayoutManager);
postLists=new ArrayList<>();
postAdapter=new PostAdapter(this, postLists);
recyclerView.setAdapter(postAdapter);
readGlobalPosts();
}
private void readGlobalPosts(){
DatabaseReference reference= FirebaseDatabase.getInstance().getReference("Posts");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
postLists.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()){
Post post=snapshot.getValue(Post.class);
assert post !=null;
postLists.add(post);
}
postAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
I get a fatal exception: main and my app crashes when i click on a users name to go to their profile. I am not sure why this is happening so any help is greatly appreciated.
There is one bit of your code I can see that will crash if asserts are enabled:
for (DataSnapshot snapshot : dataSnapshot.getChildren()){
Post post=snapshot.getValue(Post.class);
assert post !=null; // THIS
postLists.add(post);
}
What you have written there is the equivalent of:
for (DataSnapshot snapshot : dataSnapshot.getChildren()){
Post post=snapshot.getValue(Post.class);
if(post == null) {
throw new IllegalStateException("Post was null");
}
postLists.add(post);
}
and I am sure you don't want to crash your whole app when there is no Post?
If you want to test if it exists (and get feedback if it doesn't), try something like this:
for (DataSnapshot snapshot : dataSnapshot.getChildren()){
Post post=snapshot.getValue(Post.class);
if(post == null) {
Log.w("TUT", "Expected a post and didn't get one.");
} else {
postLists.add(post);
}
}
Ref:
https://en.wikibooks.org/wiki/Java_Programming/Keywords/assert
How to use assert in android?

Access arraylist on a method

I am a beginner in android development.I faces a problem with arraylist.I declared arraylist city as global variable and I added elements to it from firebase.But.,after that when i access this elements out side of the addchildevent listener method,the array list become empty.How can i declare the array list to get elements globally.?
My code snippet is,
public class BookingDetails extends Fragment {
private RecyclerView recyclerView;
private DatabaseReference dataRef;
private FirebaseAuth mAuth;
ArrayList<String> uids=new ArrayList<String>();
private ArrayList<String> dates=new ArrayList<>();
private int hour;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
InputMethodManager in=(InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
in.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(),InputMethodManager.HIDE_NOT_ALWAYS);
final View v=inflater.inflate(R.layout.activity_booking_details,container,false);
recyclerView = (RecyclerView) v.findViewById(R.id.book_detail_view);
recyclerView.setHasFixedSize(true);
LinearLayoutManager llm = new LinearLayoutManager(getActivity());
llm.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(llm);
recyclerView.addItemDecoration(new SimpleDividerItemDecoration(getActivity()));
mAuth=FirebaseAuth.getInstance();
final String user=mAuth.getCurrentUser().getUid();
dataRef= FirebaseDatabase.getInstance().getReference();
dataRef.child("Users").child(user).child("booked docters").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot data:dataSnapshot.getChildren()) {
uids.add(data.getKey());
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Toast.makeText(getActivity(),uids.get(0), Toast.LENGTH_SHORT).show();
return v;
}
}
This gives me empty.But when i use this toast on the method value event listener gives correct elements.How to fix this problem.?
Mehmed's reason on what's going wrong is correct. You'll need to move the code that needs access to the uids into the `onDataChange method. One way to do so is:
dataRef= FirebaseDatabase.getInstance().getReference();
dataRef.child("Users").child(user).child("booked docters").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot data:dataSnapshot.getChildren()) {
uids.add(data.getKey());
}
Toast.makeText(getActivity(),uids.get(0), Toast.LENGTH_SHORT).show();
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
});
Firebase listeners are asynchronous, so use your arraylist inside your Firebase listener after it is filled with data as follows:
ArrayList<String> itemList;
private void someFunction() {
itemList = new ArrayList<>();
someDatabaseRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot child : snapshot.getChildren()) {
String item = child.getKey();
itemList.add(item);
}
// Now your itemList is filled and ready to be used...
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
// If you try to use itemList here then you may get error since it is empty...
}

Categories