读取Firebase数据时,永远不会调用onDataChange

时间:2017-06-24 23:22:50

标签: android firebase firebase-realtime-database

我是新来的,目前我正在做正在处理背景和检查手机中的流程的应用,如果"com.igg.castleclash"正在进程中列表它将castleclash值设置为true并在Firebase中保存数据。一切正常,但我无法使用addValueEventListener从Firebase读取数据。

**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;
    }
}

为什么这不起作用?

2 个答案:

答案 0 :(得分:3)

有很多问题。最重要的是,您认为此处理“在后台”发生。它在主线程上运行。这是与documentation

中描述的服务的常见误解
  

什么是服务?

     

关于Service类的大多数混淆实际上围绕着什么   它

     
      
  • 服务不是一个单独的过程。 Service对象本身并不意味着它在自己的进程中运行;除非另有   指定,它在与它所属的应用程序相同的进程中运行   的。
  •   
  • 服务不是线程。它不是从主线程开始工作的手段(以避免应用程序无响应错误)。
  •   

IntentService是一个方便的服务子类,用于完成主线程的工作。

while(true)中的startTimer()循环无休止地运行。 addValueEventListener()中对onStartCommend()的调用永远不会执行,因为startTimer()永远不会返回。

数据库更改侦听器在主线程上运行。因为主线程被wait()的调用阻止,所以onDataChange()回调将无法运行(如果成功添加了侦听器)。

另外,要查看您对startTimer()中的数据库的写入是否失败,请添加CompletionListener。失败的最常见原因是由不正确的安全规则导致的权限被拒绝。

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());
        }
    }
});

答案 1 :(得分:1)

你看过David East的这段视频吗?  https://youtu.be/lpFDFK44pX8 我遵循他的方法,它有很多帮助。

第一行,你应该这样写,

  

DatabaseReference dbRef = FirebaseDatabase.getInstance()。getReference

然后,您需要为控制台中的每个数据库声明另一个DatabaseReference。

  

DatabaseReference moooww = dbRef.child(“nameOfYourDbValue”);

视频中显示的其余部分。