Firestore only updates when accessed through a specific Android activity

5 days ago 7
ARTICLE AD BOX

I'm working on an Android app where users can add and remove restaurants from their favourites via the RestaurantPage activity. When I access the RestaurantPage activity from the UserFavourites activity and attempt to remove the restaurant from my favourites, Firestore successfully updates, removing the restaurant from my favourites in the database. However, when I access a restaurant via the Search activity, I cannot remove the restaurant from my favourites (Firestore isn't updated when the favourite button is clicked). Here is the code for my RestaurantPage activity, UserFavourites activity, Search activity and AppManager class. Any help would be much appreciated! (imports are not shown, and the restaurant sort methods in AppManager are not shown)

public class RestaurantPage extends AppCompatActivity { Button favourited; TextView overall_score; RatingBar overall_rating; TextView taste_score; RatingBar taste_rating; TextView price_score; RatingBar price_rating; TextView hygiene_score; RatingBar hygiene_rating; TextView walking_score; RatingBar walking_rating; TextView waiting_score; RatingBar waiting_rating; TextView description; TextView title; FirebaseAuth authenticate; RecyclerView reviews; ImageButton locate; Button addReview; private DrawerLayout nav_layout; private Toolbar nav_toolbar; private NavigationView nav_view; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); EdgeToEdge.enable(this); setContentView(R.layout.menu_restaurantpage); nav_layout = findViewById(R.id.nav_layout); nav_toolbar = findViewById(R.id.nav_toolbar); nav_view = findViewById(R.id.navigationView); nav_view.setItemIconTintList(null); title = findViewById(R.id.title); description = findViewById(R.id.description); overall_score = findViewById(R.id.overall_score); overall_rating = findViewById(R.id.overall_rating); taste_score = findViewById(R.id.taste_score); taste_rating = findViewById(R.id.taste_rating); price_score = findViewById(R.id.price_score); price_rating = findViewById(R.id.price_rating); hygiene_score = findViewById(R.id.hygiene_score); hygiene_rating = findViewById(R.id.hygiene_rating); walking_score = findViewById(R.id.walking_score); walking_rating = findViewById(R.id.walking_rating); waiting_score = findViewById(R.id.waiting_score); waiting_rating = findViewById(R.id.waiting_rating); favourited = findViewById(R.id.favouriteButton); locate = findViewById(R.id.locate_button); addReview = findViewById(R.id.addReview); authenticate = FirebaseAuth.getInstance(); Restaurant currRestaurant = AppManager.getCurrentRestaurant(); title.setText(currRestaurant.getName()); description.setText(currRestaurant.getDescription()); overall_score.setText("" + currRestaurant.getOverallRating()); taste_score.setText("" + currRestaurant.getTasteRating()); price_score.setText("" + currRestaurant.getPriceRating()); hygiene_score.setText("" + currRestaurant.getHygieneRating()); walking_score.setText("" + currRestaurant.getWalkingTimeRating()); waiting_score.setText("" + currRestaurant.getWaitingTimeRating()); overall_rating.setNumStars(5); overall_rating.setRating((float)currRestaurant.getOverallRating()); taste_rating.setNumStars(5); taste_rating.setRating((float)currRestaurant.getTasteRating()); price_rating.setNumStars(5); price_rating.setRating((float)currRestaurant.getPriceRating()); hygiene_rating.setNumStars(5); hygiene_rating.setRating((float)currRestaurant.getHygieneRating()); walking_rating.setNumStars(5); walking_rating.setRating((float)currRestaurant.getWalkingTimeRating()); waiting_rating.setNumStars(5); waiting_rating.setRating((float)currRestaurant.getWaitingTimeRating()); ArrayList<Restaurant> currFavourites = AppManager.getCurrentUser().getFavourites(); Log.d("CURR USER", AppManager.getCurrentUser().getUsername()); int i = 0; boolean flag = false; while (i < currFavourites.size() && !flag){ if (currFavourites.get(i).getName().equals(currRestaurant.getName())){ flag = true; } i++; } if (flag) { favourited.setText("Remove from favourites"); } else { favourited.setText("Add to favourites"); } favourited.setOnClickListener((view) -> { ArrayList<Restaurant> currentFavourites = AppManager.getCurrentUser().getFavourites(); int j = 0; boolean flag2 = false; while (j < currentFavourites.size() && !flag2) { if (currentFavourites.get(j).getName().equals(currRestaurant.getName())) { flag2 = true; } j++; } if (flag2) { AppManager.getCurrentUser().removeFavourite(currRestaurant); favourited.setText("Add to favourites"); } else { AppManager.getCurrentUser().addFavourite(currRestaurant); favourited.setText("Remove from favourites"); } AppManager.uploadUser(AppManager.getCurrentUser()); }); locate.setOnClickListener((view2) -> { String mapLink = currRestaurant.getMapLink(); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse(mapLink)); startActivity(intent); }); ActionBarDrawerToggle toggleView = new ActionBarDrawerToggle(this, nav_layout, nav_toolbar, R.string.open_nav, R.string.close_nav); nav_layout.addDrawerListener(toggleView); toggleView.syncState(); nav_view.setNavigationItemSelectedListener((item) ->{ if (item.getItemId() == R.id.nav_home){ Log.d("NEWPAGE", "User sent to home screen"); startActivity(new Intent(RestaurantPage.this, HomeScreen.class)); } else if (item.getItemId() == R.id.nav_favourites){ Log.d("NEWPAGE", "User sent to favourites"); startActivity(new Intent(RestaurantPage.this, UserFavourites.class)); } else if (item.getItemId() == R.id.nav_search){ Log.d("NEWPAGE", "User sent to search page"); startActivity(new Intent(RestaurantPage.this, Search.class)); } else if (item.getItemId() == R.id.nav_info){ Log.d("NEWPAGE", "User sent to info"); startActivity(new Intent(RestaurantPage.this, AppInfo.class)); } nav_layout.closeDrawers(); return true; }); } } public class UserFavourites extends AppCompatActivity implements AdapterView.OnItemSelectedListener { private FirebaseAuth authenticate; private ArrayList<User> userList; private User currentUser; private SearchView favouritesBar; private RecyclerView favouritesRecyclerView; private SearchAdapter searchAdapter; private Spinner favouritesSpinner; private String[] sort_choices = { "A-Z", "Z-A", "Newest", "Oldest", "Highest rated" }; private DrawerLayout nav_layout; private Toolbar nav_toolbar; private NavigationView nav_view; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); EdgeToEdge.enable(this); setContentView(R.layout.menu_favourites); authenticate = FirebaseAuth.getInstance(); nav_layout = findViewById(R.id.nav_layout); nav_toolbar = findViewById(R.id.nav_toolbar); nav_view = findViewById(R.id.navigationView); nav_view.setItemIconTintList(null); favouritesRecyclerView = findViewById(R.id.favourites_list); favouritesRecyclerView.setItemAnimator(new DefaultItemAnimator()); favouritesRecyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL)); currentUser = AppManager.getCurrentUser(); if (currentUser == null){ Log.d( "USER FAIL", "No user found"); startActivity(new Intent(UserFavourites.this, HomeScreen.class)); return; } else { Log.d("USER FOUND", "User found"); } searchAdapter = new SearchAdapter(currentUser.getFavourites(), UserFavourites.this, new SearchAdapter.ItemClickListener() { @Override public void onItemClick(Restaurant restaurant) { Log.d("NEWPAGE", "User sent to restaurant page for " + restaurant.getName()); AppManager.setCurrentRestaurant(restaurant); startActivity(new Intent(UserFavourites.this, RestaurantPage.class)); } }); searchAdapter.notifyDataSetChanged(); favouritesRecyclerView.setLayoutManager(new LinearLayoutManager(this)); favouritesRecyclerView.setAdapter(searchAdapter); favouritesBar = findViewById(R.id.favourites_searchbar); favouritesBar.clearFocus(); favouritesBar.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String query) { return false; } @Override public boolean onQueryTextChange(String newText) { filterSearch(newText); return true; } }); favouritesSpinner = findViewById(R.id.favourites_spinner); favouritesSpinner.setOnItemSelectedListener(this); ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, sort_choices); spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); favouritesSpinner.setAdapter(spinnerAdapter); ActionBarDrawerToggle toggleView = new ActionBarDrawerToggle(this, nav_layout, nav_toolbar, R.string.open_nav, R.string.close_nav); nav_layout.addDrawerListener(toggleView); toggleView.syncState(); nav_view.setNavigationItemSelectedListener((item) ->{ if (item.getItemId() == R.id.nav_home){ Log.d("NEWPAGE", "User sent to home screen"); startActivity(new Intent(UserFavourites.this, HomeScreen.class)); } else if (item.getItemId() == R.id.nav_favourites){ Log.d("NEWPAGE", "User sent to favourites"); startActivity(new Intent(UserFavourites.this, UserFavourites.class)); } else if (item.getItemId() == R.id.nav_search){ Log.d("NEWPAGE", "User sent to search page"); startActivity(new Intent(UserFavourites.this, Search.class)); } else if (item.getItemId() == R.id.nav_info){ Log.d("NEWPAGE", "User sent to info"); startActivity(new Intent(UserFavourites.this, AppInfo.class)); } nav_layout.closeDrawers(); return true; }); } public void filterSearch(String filter){ ArrayList<Restaurant> filterSearch = new ArrayList<Restaurant>(); for (Restaurant restaurant : currentUser.getFavourites()){ if (restaurant.getName().toLowerCase().contains(filter.toLowerCase())){ filterSearch.add(restaurant); } } if (filterSearch.isEmpty()){ Toast.makeText(this, "No restaurants found", Toast.LENGTH_SHORT).show(); } else{ searchAdapter.setFilteredList(filterSearch); } } @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id){ if (position == 0){ searchAdapter.setFilteredList(AppManager.sortRestaurantByAZ(currentUser.getFavourites())); } else if (position == 1){ searchAdapter.setFilteredList(AppManager.sortRestaurantByZA(currentUser.getFavourites())); } else if (position == 2){ searchAdapter.setFilteredList(AppManager.sortRestaurantsByNewest(currentUser.getFavourites())); } else if (position == 3) { searchAdapter.setFilteredList(AppManager.sortRestaurantsByOldest(currentUser.getFavourites())); } else { searchAdapter.setFilteredList(AppManager.sortRestaurantsByRating(currentUser.getFavourites())); } } @Override public void onNothingSelected(AdapterView<?> parent){ } } public class Search extends AppCompatActivity implements AdapterView.OnItemSelectedListener { protected ArrayList<Restaurant> searchList; protected RecyclerView searchRecyclerView; protected SearchView searchBar; SearchAdapter searchAdapter; Spinner searchSpinner; private String[] sort_choices = { "A-Z", "Z-A", "Newest", "Oldest", "Highest rated" }; private DrawerLayout nav_layout; private Toolbar nav_toolbar; private NavigationView nav_view; private ArrayList<User> userList; private User currentUser; private FirebaseAuth authenticate; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); EdgeToEdge.enable(this); setContentView(R.layout.menu_searchpage); nav_layout = findViewById(R.id.nav_layout); nav_toolbar = findViewById(R.id.nav_toolbar); nav_view = findViewById(R.id.navigationView); nav_view.setItemIconTintList(null); searchRecyclerView = findViewById(R.id.search_list); searchRecyclerView.setItemAnimator(new DefaultItemAnimator()); searchRecyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL)); searchList = AppManager.getRestaurants(); authenticate = FirebaseAuth.getInstance(); currentUser = AppManager.getCurrentUser(); if (currentUser == null){ Log.d( "USER FAIL", "No user found"); startActivity(new Intent(Search.this, HomeScreen.class)); return; } else { Log.d("USER FOUND", "User found"); ArrayList<Restaurant> currList = currentUser.getFavourites(); } searchAdapter = new SearchAdapter(searchList, Search.this, new SearchAdapter.ItemClickListener() { @Override public void onItemClick(Restaurant restaurant) { Log.d("NEWPAGE", "User sent to restaurant page for " + restaurant.getName()); AppManager.setCurrentRestaurant(restaurant); startActivity(new Intent(Search.this, RestaurantPage.class)); } }); searchAdapter.notifyDataSetChanged(); searchRecyclerView.setLayoutManager(new LinearLayoutManager(this)); searchRecyclerView.setAdapter(searchAdapter); searchBar = findViewById(R.id.search_bar); searchBar.clearFocus(); searchBar.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String query) { return false; } @Override public boolean onQueryTextChange(String newText) { filterSearch(newText); return true; } }); searchSpinner = findViewById(R.id.search_spinner); searchSpinner.setOnItemSelectedListener(this); ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, sort_choices); spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); searchSpinner.setAdapter(spinnerAdapter); ActionBarDrawerToggle toggleView = new ActionBarDrawerToggle(this, nav_layout, nav_toolbar, R.string.open_nav, R.string.close_nav); nav_layout.addDrawerListener(toggleView); toggleView.syncState(); nav_view.setNavigationItemSelectedListener((item) ->{ if (item.getItemId() == R.id.nav_home){ Log.d("NEWPAGE", "User sent to home screen"); startActivity(new Intent(Search.this, HomeScreen.class)); } else if (item.getItemId() == R.id.nav_favourites){ Log.d("NEWPAGE", "User sent to favourites"); startActivity(new Intent(Search.this, UserFavourites.class)); } else if (item.getItemId() == R.id.nav_search){ Log.d("NEWPAGE", "User sent to search page"); startActivity(new Intent(Search.this, Search.class)); } else if (item.getItemId() == R.id.nav_info){ Log.d("NEWPAGE", "User sent to info"); startActivity(new Intent(Search.this, AppInfo.class)); } nav_layout.closeDrawers(); return true; }); } public void filterSearch(String filter){ ArrayList<Restaurant> filterSearch = new ArrayList<Restaurant>(); for (Restaurant restaurant : searchList){ if (restaurant.getName().toLowerCase().contains(filter.toLowerCase())){ filterSearch.add(restaurant); } } if (filterSearch.isEmpty()){ Toast.makeText(this, "No restaurants found", Toast.LENGTH_SHORT).show(); } else{ searchAdapter.setFilteredList(filterSearch); } } @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id){ if (position == 0){ searchAdapter.setFilteredList(AppManager.sortRestaurantByAZ(searchList)); } else if (position == 1){ searchAdapter.setFilteredList(AppManager.sortRestaurantByZA(searchList)); } else if (position == 2){ searchAdapter.setFilteredList(AppManager.sortRestaurantsByNewest(searchList)); } else if (position == 3) { searchAdapter.setFilteredList(AppManager.sortRestaurantsByOldest(searchList)); } else { searchAdapter.setFilteredList(AppManager.sortRestaurantsByRating(searchList)); } } @Override public void onNothingSelected(AdapterView<?> parent){ } } public class AppManager { private static int numOfRestaurants; private static FirebaseFirestore db = FirebaseFirestore.getInstance(); private static ArrayList<User> users = new ArrayList<User>(); protected static ArrayList<Restaurant> restaurants = new ArrayList<Restaurant>(); private static Restaurant currentRestaurant; private static User currentUser; public static ArrayList<User> getUsersImmediately(){ return users; } public static ArrayList<User> getUsers(){ users.clear(); db.collection("users").get() .addOnCompleteListener((task) -> { if (task.isSuccessful()) { for (QueryDocumentSnapshot document : task.getResult()) { users.add(document.toObject(User.class)); Log.d("USER ADD", "Added user to user list"); } Log.d("DOWNLOAD DB", "Successfully obtained users"); } }) .addOnFailureListener((task) -> { Log.d("DOWNLOAD DB", "Failed to obtain users"); }); return users; } public static void downloadRestaurants(){ restaurants.clear(); db.collection("restaurants").get() .addOnCompleteListener((task) -> { if (task.isSuccessful()) { for (QueryDocumentSnapshot document : task.getResult()) { restaurants.add(document.toObject(Restaurant.class)); Log.d("RESTAURANT ADD", "Added restaurant to restaurant list"); } Log.d("DOWNLOAD DB", "Successfully downloaded restaurants"); } }) .addOnFailureListener((task) -> { Log.d("DOWNLOAD DB", "Failed to download restaurants"); }); } public static void downloadUsers(){ users.clear(); db.collection("users").get() .addOnCompleteListener((task) -> { if (task.isSuccessful()) { for (QueryDocumentSnapshot document : task.getResult()) { users.add(document.toObject(User.class)); Log.d("USER ADD", "Added user to user list"); } Log.d("DOWNLOAD DB", "Successfully downloaded users"); } }) .addOnFailureListener((task) -> { Log.d("DOWNLOAD DB", "Failed to download users"); }); } public static void uploadUser(User user){ db.collection("users").document(user.getUsername()) .set(user) .addOnSuccessListener((task) -> { Log.d("UPLOAD DB", "User " + user.getUsername() + " uploaded to database"); }) .addOnFailureListener((task) ->{ Log.d("UPLOAD DB", "User could not be uploaded"); }); } public static boolean userExists(String username) { for (int i = 0; i < users.size(); i++) { if (users.get(i).getUsername().equals(username)){ return false; } } return true; } public static ArrayList<Restaurant> getRestaurants(){ restaurants.clear(); db.collection("restaurants").get() .addOnCompleteListener((task) -> { if (task.isSuccessful()) { for (QueryDocumentSnapshot document : task.getResult()) { restaurants.add(document.toObject(Restaurant.class)); Log.d("RESTAURANT ADD", "Added restaurant to restaurant list"); } Log.d("DOWNLOAD DB", "Successfully obtained restaurants"); } }) .addOnFailureListener((task) -> { Log.d("DOWNLOAD DB", "Failed to obtain restaurants"); }); return restaurants; } public static boolean restaurantExists(String name) { for (int i = 0; i < restaurants.size(); i++) { if (restaurants.get(i).getName().equals(name)){ return false; } } return true; } public static void addUser(User user) { users.add(user); db.collection("users").document(user.getUsername()) .set(user) .addOnSuccessListener((ref) -> { Log.d("UPLOAD DB", "User " + user.getUsername() + " uploaded to database"); }) .addOnFailureListener((ref) ->{ Log.d("UPLOAD DB", "User could not be uploaded"); }); } public static void addRestaurant(Restaurant restaurant) { restaurants.add(restaurant); db.collection("restaurants").document(restaurant.getName()) .set(restaurant) .addOnSuccessListener((ref) ->{ Log.d("UPLOAD DB", "Restaurant " + restaurant.getName() + " uploaded to database"); }) .addOnFailureListener((ref) -> { Log.d("UPLOAD DB", "Restaurant failed to upload to database"); }); } public static void setNumOfRestaurants(){ AggregateQuery countQuery = db.collection("restaurants").count(); countQuery.get(AggregateSource.SERVER).addOnCompleteListener((task) -> { if (task.isSuccessful()){ AggregateQuerySnapshot result = task.getResult(); numOfRestaurants = (int)result.getCount(); Log.d("COUNT RESTAURANTS", "Counted " + numOfRestaurants + " restaurants"); } }); } public static Restaurant getRestaurant(int i){ return restaurants.get(i); } public static int getNumOfRestaurants(){ setNumOfRestaurants(); return numOfRestaurants; } public static Restaurant getCurrentRestaurant() { return currentRestaurant; } public static void setCurrentRestaurant(Restaurant newCurrent) { currentRestaurant = newCurrent; } public static User getCurrentUser() { return currentUser; } public static void setCurrentUser(User currentUser) { AppManager.currentUser = currentUser; } }
Read Entire Article