0

im working with firebase-realtime on android studio java. I have several classes that read and write data from/to Firebase. what is the best way to do it and avoid code duplication ? i try static singelton class called "FirebaseManager" to hold all firebase function. i dont get the result when try to read data, I understood that this is because Firebase works asynchronously. Is there a way around this or a better way to work with firebase in my classes ? Thanks.

public class FirebaseManager {

    private static FirebaseManager instance;
    private static FirebaseAuth mFirebaseAuth;
    private static FirebaseDatabase mFirebaseDatabase;

    private FirebaseManager() {
        mFirebaseAuth = FirebaseAuth.getInstance();
        mFirebaseDatabase = FirebaseDatabase.getInstance();
    }

    public static synchronized FirebaseManager getInstance() {
        if (instance == null) {
            instance = new FirebaseManager();
        }

        return instance;
    }

    public FirebaseAuth getFirebaseAuth() {
        return mFirebaseAuth;
    }

    public FirebaseDatabase getFirebaseDatabase() {
        return mFirebaseDatabase;
    }

public static List<GameScore> getQuizScoresFromFirebase(){
    FirebaseUser firebaseUser = mFirebaseAuth.getCurrentUser();
    DatabaseReference mDatabaseReference;

    List<GameScore> gamescores = new ArrayList<>();

    if (firebaseUser != null){

        mDatabaseReference = mFirebaseDatabase.getReference("Users/" + firebaseUser.getUid() + "/quizScoreList");
        mDatabaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                //checking if QuizScoresList exists in the current firebase user
                if (dataSnapshot.exists()){
                    long size = dataSnapshot.getChildrenCount();
                    Log.d("MyTag", "dataSnapshot is exists " + "dataSnapshot count: "+ size);
                    for (DataSnapshot scoreSnapshot : dataSnapshot.getChildren()) {
                        GameScore gs = scoreSnapshot.getValue(GameScore.class);
                        Log.d("MyTag","GameScore: "+ gs.toString());
                        gamescores.add(gs);
                        // here gamescores look good and filled with data
                        Log.d("MyTag","gamescores: "+ gamescores.size());
                    }

                } else {
                    // need to be hundle
                }
            }
            @Override
            public void onCancelled(DatabaseError databaseError) {
                //Toast.makeText(QuizScore.this, "Error on get scores from Firebase", Toast.LENGTH_SHORT).show();
            }
        });
    }
    return gamescores;
}
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Ohad
  • 17
  • 4
  • Asking for the best way to do something may get your question closed as it's asking for something that tends to be rather opinionated. If you can't get your code to work, describe clear what isn't working and how you debugged the problem already. For example: If you set a breakpoint on each line of the code you shared, run the code in a debugger, and then check the value of each variable on each line, which is the **first** line that doesn't do what you expect it to do? – Frank van Puffelen Mar 05 '23 at 18:05
  • In the code you shared, two things you need to fix: 1) Implement the `else` for `if (dataSnapshot.exists()){` so that you get a clearly defined behavior (e.g. an error message) if the data doesn't exist. 2) Implement `onCancelled` as you're ignoring possible errors now. At its minimum it should be `public void onCancelled(@NonNull DatabaseError databaseError) { throw databaseError.toException(); }`. Neither of these **is** the problem, but they may help you *find* the problem. – Frank van Puffelen Mar 05 '23 at 18:06
  • There is no way you return the `gamescores` as a result of a method. Firebase API is asynchronous. So please check the duplicate to see how can you solve this using a callback. You might also be interested in reading this [resource](https://medium.com/firebase-tips-tricks/how-to-read-data-from-firebase-realtime-database-using-get-269ef3e179c5). – Alex Mamo Mar 06 '23 at 09:59
  • hey Frank. thanks for the response. and sorry for the difficulty in understanding the question. what I meant is that `getQuizScoresFromFirebase()` return the `gamescores` list empty because it dosnt wait for `onDataChange` to finish. when i print to logcat the list inside `onDataChange` it looks good. but the list return empty from `getQuizScoresFromFirebase()` – Ohad Mar 06 '23 at 10:06

0 Answers0