Reading Firebase data, onDataChange is never called

I am new to here, I am currently working on an application that works on the background and checks the processes in the phone if "com.igg.castleclash"

in processes. The list sets the value of lockclash to true and stores the data in Firebase. Everything works fine, but I cannot read data from Firebase using addValueEventListener

.

** Firebase data img **

public class SensorService extends Service {
    boolean castleclash = false;
    DatabaseReference databaaseUsers;


    public SensorService(Context applicationContext) {
        super();
    }

    public SensorService() {
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);

        startTimer();

            databaaseUsers.child("user1").addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

                UsersData user = dataSnapshot.getValue(UsersData.class);
                Log.i("user name", user.getName());
            }

            @Override
            public void onCancelled(DatabaseError error) {
                // Failed to read value
                Log.w("Failed to read value.", error.toException());
            }
        });

        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
            Intent broadcastIntent = new
                    Intent("uk.ac.shef.oak.ActivityRecognition.RestartSensor");
            sendBroadcast(broadcastIntent);


    }
    public void startTimer() {
        synchronized (this) {
            while (true) {

                try {
                    wait(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                databaaseUsers = FirebaseDatabase.getInstance().getReference();
                ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
                final List<ActivityManager.RunningAppProcessInfo> runningProcesses = manager.getRunningAppProcesses();

                for (ActivityManager.RunningAppProcessInfo process : runningProcesses) {
                    if (process.processName.equals("com.igg.castleclash")) {
                        castleclash = true;
                        break;
                    } else {
                        castleclash = false;

                    }
                }

                UsersData user1 = new UsersData(castleclash, "name");
                databaaseUsers.child("user1").setValue(user1);

            }

        }

    }



    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

      

Any ideas why this isn't working?

+3


source to share


2 answers


There are several problems. Most importantly, this processing does not happen "in the background" as you might think. It works on the main thread. This is a common misunderstanding with the Services, described in the documentation :

What is a service?

Much confusion about the Service class actually revolves around the fact that it is not:

  • The service is not a separate process. The service object itself does not imply that it is running in its own process; unless otherwise specified, it runs in the same process as the application it is part of.
  • Service is not a thread. This does not mean that you have to do the work of the main thread (to avoid errors associated with an application error).

An IntentService is a convenient subclass of the Service for doing work from the main thread.

The cycle while(true)

c startTimer()

runs endlessly. The call addValueEventListener()

to is onStartCommend()

never executed, because it startTimer()

never returns.



Database change listeners run on the main thread. Since the main thread is blocked by the call wait()

, the callback onDataChange()

will fail (if the listener was added successfully).

Also, to check if your database entry failed in startTimer()

, add CompletionListener

. The most common cause of failure is access denied due to inappropriate security rules.

UsersData user1 = new UsersData(castleclash, "name");
databaaseUsers.child("user1").setValue(user1, new DatabaseReference.CompletionListener() {
    @Override
    public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
        if (databaseError == null) {
            Log.d(TAG, "onComplete: success");
        } else {
            Log.e(TAG, "onComplete: failed", databaseError.toException());
        }
    }
});

      

+3


source


Are you viewing this video from David East?  https://youtu.be/lpFDFK44pX8 I am following his method and it helps a lot.

On the first line, you should write it like this:

DatabaseReference dbRef = FirebaseDatabase.getInstance (). getReference



Then you will need to declare a different DatabaseReference for each db in the console.

DatabaseReference moooww = dbRef.child ("nameOfYourDbValue");

The rest is shown in the video.

+1


source







All Articles