I have an android app with the following MainActivity.java. When I open the app, Firebase records 37 reads from the database. I don't understand why. The log under TagDB only shows one line, this: 2024-02-08 23:16:37.421 32512-32512 TagDB                   com.asd.BeST                 D  User Firebase score: 0

I think it should only count 1 reads, because I only want to read the document related to the current UserID. Why does it count more reads? (BTW the database has 14 documents inside it)


public class MainActivity extends BaseDrawerActivity {

    //variables
    private InterstitialAd mInterstitialAd;
    private RewardedAd mRewardedAd;
    private static FirebaseAuth mAuth;
    private static FirebaseFirestore db = FirebaseFirestore.getInstance();
    static CollectionReference usersRef = db.collection("users");

    public static int amount = 0;
    boolean state = false;
    static boolean changedSinceSynced = true;


    private TextView mTextView;
    String text;


    //menu var
    DrawerLayout drawerLayout;
    NavigationView navigationView;
    //ActionBarDrawerToggle drawerToggle;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // menuRelated
        initializeDrawer();

        //Initialize AdMob
        MobileAds.initialize(this, new OnInitializationCompleteListener() {
            @Override
            public void onInitializationComplete(@NonNull InitializationStatus initializationStatus) {
            }
        });

        //RewardedAdRelated
        loadRewardedAds();
        Button rewardedButton = findViewById(R.id.RewardedbtnAds);
        rewardedButton.setOnClickListener(view -> {
            showRewardedAds();
        });

        //InterstitialAdRelated
        loadInterstitialAd();
        Button interstitialButton = findViewById(R.id.IntbtnAds);
        interstitialButton.setOnClickListener(view -> {
           showInterstitialAd();
        });

        //BannerAdRelated
        Button bannerButton = findViewById(R.id.BannerbtnAds);
        bannerButton.setOnClickListener(view -> {
            bannerAd();
        });


        //ResetButtonRelated
        resetButton();

        //FirebaseAuth
        mAuth = FirebaseAuth.getInstance();
        FirebaseUser currentUser = mAuth.getCurrentUser(); //if user is signed in returns UID, else null
        updateUI(currentUser); //if userID is null, generated.

        //CoinRelated
        loadCoins();


    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d("TagDB", "onStopped");
        if (changedSinceSynced) {
            saveToDB(false, new DbOperationCompleteListener() {
                @Override
                public void onDbOperationComplete() {
                    changedSinceSynced = false;
                    Log.d("TagDB", "onStopped, synced to DB, changedSinceSynced set to false");

                }
            });
        }

    }

    //bannerAds
    private void bannerAd() {
        AdView mAdView = findViewById(R.id.adView);
        AdRequest BannerAdRequest = new AdRequest.Builder().build();
        if (!state) {
            mAdView.loadAd(BannerAdRequest);
            mAdView.setVisibility(View.VISIBLE);
            state = true;
        } else {
            mAdView.setVisibility(View.GONE);
            state = false;
        }
    }

    //interstitialAds
    private void loadInterstitialAd() {
        AdRequest interstitialAdRequest = new AdRequest.Builder().build();
        InterstitialAd.load(this,getString(R.string.INTERSTITIAL_AD_UNIT_ID), interstitialAdRequest, new InterstitialAdLoadCallback() {
            @Override
            public void onAdLoaded(@NonNull InterstitialAd interstitialAd) {
                super.onAdLoaded(interstitialAd);
                mInterstitialAd = interstitialAd;
                interstitialAd.setFullScreenContentCallback(new FullScreenContentCallback(){
                    @Override
                    public void onAdClicked() {
                        super.onAdClicked();
                    }
                    @Override
                    public void onAdDismissedFullScreenContent() {
                        mInterstitialAd = null;
                        loadInterstitialAd();
                    }

                    @Override
                    public void onAdFailedToShowFullScreenContent(@NonNull AdError adError) {
                        mInterstitialAd = null;
                    }
                });
            }

                @Override
                public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
                    mInterstitialAd = null;
                    //error message is managed in showInterstitialAds() function
                }
            });
    }
    private void showInterstitialAd() {
        if (mInterstitialAd!=null) {
            mInterstitialAd.show(MainActivity.this);
        } else {
            Log.d("TAG", "The interstitial ad is not ready yet. Try again!");
            loadInterstitialAd(); // Try to load again if it wasn’t ready when the button was clicked
        }
    }

    //rewardedAds
    private void loadRewardedAds() {
        AdRequest RewardedAdRequest = new AdRequest.Builder().build();
        RewardedAd.load(this, getString(R.string.REWARDED_AD_UNIT_ID), RewardedAdRequest, new RewardedAdLoadCallback() {
            @Override
            public void onAdLoaded(@NonNull RewardedAd rewardedAd) {
                super.onAdLoaded(rewardedAd);
                mRewardedAd = rewardedAd;
                rewardedAd.setFullScreenContentCallback(new FullScreenContentCallback() {
                    @Override
                    public void onAdClicked() {
                        super.onAdClicked();
                    }

                    @Override
                    public void onAdDismissedFullScreenContent() {
                        super.onAdDismissedFullScreenContent();
                        loadRewardedAds();
                    }

                    @Override
                    public void onAdFailedToShowFullScreenContent(@NonNull AdError adError) {
                        super.onAdFailedToShowFullScreenContent(adError);
                        mRewardedAd = null;
                    }
                });
            }
            @Override
            public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
                super.onAdFailedToLoad(loadAdError);
                mRewardedAd = null;
                //error message is managed in showRewardedAds() function
            }
        });
    }
    private void showRewardedAds() {

        if (mRewardedAd!=null) {
            mRewardedAd.show(MainActivity.this, new OnUserEarnedRewardListener() {
                @Override
                public void onUserEarnedReward(@NonNull RewardItem rewardItem) {
                    amount += rewardItem.getAmount();
                    text = getResources().getString(R.string.coins_message, amount);
                    mTextView.setText(text);
                    saveCoinAmount();
                    changedSinceSynced = true;

                }
            });
        } else {
            Toast.makeText(MainActivity.this,"Rewarded ad is not ready yet. Try again!", Toast.LENGTH_SHORT).show();
        }
    }

    //coins
    private void loadCoins(){
        loadCoinAmount(); //this is local save
        readFromDB();
        mTextView=findViewById(R.id.Coins);
        text = getResources().getString(R.string.coins_message, amount);
        mTextView.setText(text);
    }
    private void loadCoinAmount() {
        SharedPreferences sharedPreferences = getSharedPreferences("UserPreferences", MODE_PRIVATE);
        amount = sharedPreferences.getInt("coinsAmount", 0);
    }
    private void saveCoinAmount() {
        SharedPreferences sharedPreferences = getSharedPreferences("UserPreferences", MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putInt("coinsAmount", amount);
        editor.apply();
    }


    //reset
    private void resetButton(){
        Button resetButton = findViewById(R.id.resetButton);
        resetButton.setOnClickListener(view -> {
            confirmResetCoins();
        });
    }
    private void confirmResetCoins(){
        AlertDialog.Builder confirmation = new AlertDialog.Builder(this);
            confirmation.setTitle("Are you sure?");
            confirmation.setMessage("Your coin balance will be reset to 0");
            confirmation.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    resetCoins();
                }
            });
            confirmation.setNegativeButton("No", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                }
            });
            confirmation.create().show();
    }
    private void resetCoins() {
        amount = 0;
        saveCoinAmount();
        //saveToDB(false, null);
        changedSinceSynced = true;
        text = getResources().getString(R.string.coins_message, amount);
        mTextView.setText(text);
        Toast.makeText(MainActivity.this, "Coins have been reset!", Toast.LENGTH_SHORT).show();
    }

    //FirebaseAuth
    private void updateUI(FirebaseUser user) {
        if (user==null) { //if there's no user signed in
            mAuth.signInAnonymously().addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        FirebaseUser user = mAuth.getCurrentUser();
                        updateUI(user);

                    } else {
                        updateUI(null);
                    }
                }
            });
        }
    }

    //Firebase DB
    public static void saveToDB(boolean Create, @Nullable DbOperationCompleteListener listener) {
        Map<String, Object> userdb = new HashMap<>();
        userdb.put("score", amount);

        OnSuccessListener<Void> successListener = new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void unused) {
                Log.d("TagDB", "Successfully saved to DB");
                if (listener != null) {
                    listener.onDbOperationComplete();
                }
            }
        };

        OnFailureListener failureListener = new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Log.w("TagDB","Error adding document", e);
            }
        };

        if (Create) {
            usersRef.document(Objects.requireNonNull(mAuth.getUid())).set(userdb) //update-set
                    .addOnSuccessListener(successListener)
                    .addOnFailureListener(failureListener);
        } else {
            usersRef.document(Objects.requireNonNull(mAuth.getUid())).update(userdb) //update-set
                    .addOnSuccessListener(successListener)
                    .addOnFailureListener(failureListener);

        }

    }
    private void readFromDB() {
        String userId = mAuth.getUid(); // Get the current authenticated user’s ID
        if (userId == null) {
            // Handle the case where there is no authenticated user
            Log.w("TagDB", "User ID is null, can’t fetch data.");
            return;
        }

        DocumentReference docRef = usersRef.document(userId);
        docRef.get()
                .addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
                    @Override
                    public void onSuccess(DocumentSnapshot documentSnapshot) {
                        if (documentSnapshot.exists()) {
                            // Retrieves the score from the document
                            Long score = documentSnapshot.getLong("score");
                            if (Math.toIntExact(score) != amount) {
                                amount = Math.toIntExact(score);
                                mTextView=findViewById(R.id.Coins);
                                text = getResources().getString(R.string.coins_message, amount);
                                mTextView.setText(text);
                                Toast.makeText(MainActivity.this, "Local coin amount overridden by Firebase score.", Toast.LENGTH_SHORT).show();
                                saveCoinAmount();
                            }
                            changedSinceSynced = false; //false when sync, because local and cloud values match
                            Log.d("TagDB", "User Firebase score: " + score);
                        } else {
                            Log.d("TagDB", "No such document!");
                            saveToDB(true, null);

                        }
                    }
                })
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        Log.w("TagDB", "Error fetching document", e);
                    }
                });
    }

    public interface DbOperationCompleteListener {
        void onDbOperationComplete();
    }

}