【问题标题】:Firebase Realtime Get DataFirebase 实时获取数据
【发布时间】:2021-09-04 07:47:54
【问题描述】:

我正在通过 Android Studio 开发一个项目,我需要从 Firebase 实时数据库中获取数据。

public static void uploadData(String username, Measurement measurement) {

        String date = measurement.getDayTime();
        double pulse= measurement.getPulse();
        double step= measurement.getStep();
        double bodyTemp= measurement.getBodyTemp();
        double humidity= measurement.getHumidity();

        Query upload = reference.orderByChild("username").equalTo(username);

        upload.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {

                if (snapshot.exists()){
                    reference.child(username).child(date).child("pulse").setValue(pulse);
                    reference.child(username).child(date).child("step").setValue(step);
                    reference.child(username).child(date).child("bodyTemp").setValue(bodyTemp);
                    reference.child(username).child(date).child("humidity").setValue(humidity);
                }
            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {

            }
        });
    }

通过uploadData,我把它放到DB:

   public static Measurement downloadData(String username){

        //public static DatabaseReference reference = FirebaseDatabase.getInstance().getReference("healthData");

        Query query = reference.orderByChild("username").equalTo(username);

        query.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {

                if (snapshot.exists()){
                    String dateStr = "04-09-2021 09:42";
                    tempMeasurement = snapshot.child(username).child(dateStr).getValue(Measurement.class);
                }
            }
            @Override
            public void onCancelled(@NonNull DatabaseError error) {
            }
        });

        return tempMeasurement;
    }

但是当我想取回数据时,它返回 null。

这就是我尝试编写并得到空错误的方式:

        reportTV.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Measurement temp = Measurement.downloadData(username);
                Toast.makeText(getApplicationContext(), "Pulse: " + temp.getPulse(), Toast.LENGTH_SHORT ).show();
            }
        });

    }

Firebase Json 格式

    {
"healthData" : {
    "mbaykols" : {
      "04-09-2021 09:42" : {
        "bodyTemp" : 36.5,
        "humidity" : 60,
        "pulse" : 70,
        "step" : 1300
      },
      "04-09-2021 09:43" : {
        "bodyTemp" : 36.5,
        "humidity" : 60,
        "pulse" : 70,
        "step" : 1300
      },
      "04-09-2021 09:45" : {
        "bodyTemp" : 36.5,
        "humidity" : 60,
        "pulse" : 70,
        "step" : 1300
      }
    }

基本上,我需要获取数据。首先,我试图一一获得。在那之后,我会得到最后的 5 或 10。我需要的是如何接触到这个孩子。

更新 1

我在规则上所做的是

{
  "rules": {
    ".read": "now < 1632776400000",  // 2021-9-28
    ".write": "now < 1632776400000",  // 2021-9-28

    "healthData":{
      "username":{
        ".indexOn": ["date","pulse","step","bodyTemp","humidity"]
      }
    }
  }
}

更新 2

             DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
             DatabaseReference mbaykolsRef = rootRef.child("healthData").child(username);
             Query queryByName = mbaykolsRef;
             queryByName.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
                 @Override
                 public void onComplete(@NonNull Task<DataSnapshot> task) {

                     if (task.isSuccessful()) {
                         for (DataSnapshot ds : task.getResult().getChildren()) {
                             String date = ds.child("date").getValue(String.class);
                             long pulse = ds.child("pulse").getValue(long.class);
                             long step = ds.child("step").getValue(long.class);
                             long bodyTemp = ds.child("bodyTemp").getValue(long.class);
                             long humidity = ds.child("humidity").getValue(long.class);
                             Log.d("TAG", date + "/" + pulse + "/" + step + "/" + bodyTemp + "/" + humidity);
                         }
                     } else {
                         Log.d("TAG", task.getException().getMessage()); //Don't ignore potential errors!
                     }

                 }
             });

成功了。我想,它是关于 databaseReference 和查询定义的。如您所见,我更改了它们并收到类型错误。将String转换为long类型后,现在可以访问数据了

Logcat 输出:

2021-09-04 18:31:59.097 18739-18739/com.example.bitirme D/TAG: 04-09-2021 11:07:47/70/1300/36/60
2021-09-04 18:31:59.099 18739-18739/com.example.bitirme D/TAG: 04-09-2021 11:07:52/70/1300/36/60
2021-09-04 18:31:59.100 18739-18739/com.example.bitirme D/TAG: 04-09-2021 11:13:34/70/1300/36/60
2021-09-04 18:31:59.101 18739-18739/com.example.bitirme D/TAG: 04-09-2021 11:16:27/70/1300/36/60
2021-09-04 18:31:59.101 18739-18739/com.example.bitirme D/TAG: 04-09-2021 16:00:36/70/1300/36/60
2021-09-04 18:31:59.102 18739-18739/com.example.bitirme D/TAG: 04-09-2021 17:07:31/70/1300/36/60
2021-09-04 18:31:59.103 18739-18739/com.example.bitirme D/TAG: 04-09-2021 17:13:30/70/1300/36/60
2021-09-04 18:31:59.103 18739-18739/com.example.bitirme D/TAG: 04-09-2021 17:32:37/70/1300/36/60
2021-09-04 18:31:59.104 18739-18739/com.example.bitirme D/TAG: 04-09-2021 18:03:20/70/1300/36/60
2021-09-04 18:31:59.104 18739-18739/com.example.bitirme D/TAG: 04-09-2021 18:03:25/70/1300/36/60
2021-09-04 18:31:59.107 18739-18739/com.example.bitirme D/TAG: 04-09-2021 18:23:19/70/1300/36/60
2021-09-04 18:31:59.108 18739-18739/com.example.bitirme D/TAG: 04-09-2021 18:23:27/70/1300/36/60
2021-09-04 18:31:59.108 18739-18739/com.example.bitirme D/TAG: 04-09-2021 18:23:51/70/1300/36/60

【问题讨论】:

    标签: java android firebase firebase-realtime-database google-cloud-platform


    【解决方案1】:

    首先要做的事情。无需执行四种不同的setValue() 操作即可在同一个子项下添加四个值:

    reference.child(username).child(date).child("pulse").setValue(pulse);
    reference.child(username).child(date).child("step").setValue(step);
    reference.child(username).child(date).child("bodyTemp").setValue(bodyTemp);
    reference.child(username).child(date).child("humidity").setValue(humidity);
    

    您可以简单地创建一个 Map

    Map<String, Object> data = new HashMap<>();
    data.put("pulse", pulse);
    data.put("step", step);
    data.put("bodyTemp", bodyTemp);
    data.put("humidity", humidity);
    

    并执行单个操作:

    reference.child(username).child(date).setValue(data).addOnCompleteListener(/* ... /*);
    

    这更有可能被使用,因为您可以一次性添加数据。使用多个操作时,您最终可能会得到不一致的数据,因为其中一个操作可能会失败。

    现在,要获取数据,您应该像这样创建一个查询并附加一个侦听器:

    DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
    DatabaseReference mbaykolsRef = rootRef.child("healthData").child("mbaykols");
    Query queryByName = mbaykolsRef.orderByChild("username").equalTo(username);
    queryByName.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
        @Override
        public void onComplete(@NonNull Task<DataSnapshot> task) {
            if (task.isSuccessful()) {
                for (DataSnapshot ds : task.getResult().getChildren()) {
                    String pulse = ds.child("pulse").getValue(String.class);
                    String step = ds.child("step").getValue(String.class);
                    String bodyTemp = ds.child("bodyTemp").getValue(String.class);
                    String humidity = ds.child("humidity").getValue(String.class);
                    Log.d("TAG", pulse + "/" + step + "/" + bodyTemp + "/" + humidity);
                }
            } else {
                Log.d("TAG", task.getException().getMessage()); //Don't ignore potential errors!
            }
        }
    });
    

    logcat 中的结果将是:

    70/1300/36.5/60
    70/1300/36.5/60
    70/1300/36.5/60
    

    如果要限制结果,只需添加limit(5) 调用即可。

    【讨论】:

    • 2021-09-04 17:38:32.258 17116-17165/com.example.bitirme I/RepoOperation: get for query /healthData/mbaykols falling back to disk cache after error: Index not defined, add ".indexOn": "username", for path "/healthData/mbaykols", to the rules 2021-09-04 17:38:32.259 17116-17116/com.example.bitirme D/TAG: Index not defined, add ".indexOn": "username", for path "/healthData/mbaykols", to the rules
    • Give it a try 告诉我它是否有效。
    • 我尝试了一些东西,但我不确定。我得到的错误消失了,但在 Logcat 上仍然看不到任何东西
    • 是否触发了onComplete?如果您使用的是Log.d("TAG", ds.toString());,logcat 中是否会打印一些内容?
    • 我做到了。感谢您的帮助
    猜你喜欢
    • 1970-01-01
    • 2019-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-04
    • 2020-02-27
    • 1970-01-01
    • 2020-02-22
    相关资源
    最近更新 更多