Constantly check if a value is present in the firestore

I’m developing a piece of code for my application that can constantly check if a certain number exists on the firebase firestore. If nothing happens, instead if it does not exist it changes the screen. I accomplished this by using a loop that runs in one thread. This is the code:

public class testPage extends AppCompatActivity {

    Boolean accountEliminated = false;

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

        Runnable objRunnable = new Runnable(){
            @Override
            public void run() {
                while(!accountEliminated){
                    FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
                    DocumentReference docIdRef = rootRef.collection("Attesa").document("1234567890");
                    docIdRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
                        @Override
                        public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                            if (task.isSuccessful()) {
                                DocumentSnapshot document = task.getResult();
                                if (!document.exists()) {
                                    Toast.makeText(testPage.this, "Disconnected.", Toast.LENGTH_SHORT).show();
                                    accountEliminated = true;
                                    Intent intent = new Intent(getApplicationContext(), AccessPage.class);
                                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
                                    startActivity(intent);
                                }
                            }
                        }
                    });
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };

        Thread objBgThread = new Thread(objRunnable);
        objBgThread.start();
    }

}

But I think it is a method that considerably burdens my application. Also in the line where there is the Thread.sleep it warns me of a "Busy wait" and I think it is a problem. What can I do?

>Solution :

This is indeed a suboptimal way to do this on Firestore, and I highly recommend switching over to a realtime listener for this. With that you can drastically reduce and simplify the code, and it should be something like this:

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

    FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
    DocumentReference docIdRef = rootRef.collection("Attesa").document("1234567890");
    docIdRef.addSnapshotListener(new EventListener<DocumentSnapshot>() {
        @Override
        public void onEvent(@Nullable DocumentSnapshot document,
                            @Nullable FirebaseFirestoreException e) {
            if (e != null) {
                Log.w(TAG, "Listen failed.", e);
                return;
            }
    
            if (document != null && !document.exists()) {
                Toast.makeText(testPage.this, "Disconnected.", Toast.LENGTH_SHORT).show();
                accountEliminated = true;
                Intent intent = new Intent(getApplicationContext(), AccessPage.class);
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
                startActivity(intent);
            }
        }
    });
}

Leave a Reply