【问题标题】:addListenerForSingleValueEvent returns dataSnapshot value null when I add query to it当我向其添加查询时,addListenerForSingleValueEvent 返回 dataSnapshot 值 null
【发布时间】:2021-08-03 07:11:13
【问题描述】:

我正在开发一个安卓项目。有一个与 Firebase 数据库相关的错误。因此,我需要一位对 firebase 数据库非常熟悉的经验丰富的 Android 开发人员。 错误:我正在使用 addListenerForSingleValueEvent,当我尝试获取所有数据时,它返回数据,当我为 status = ACTIVE 设置查询时,即使数据库有一个 ACTIVE 条目,它也会返回 dataSnaphot null。当我使用 addValueEventListener 时,它工作正常。 请帮帮我。

private void getMeetingData(){

    //Constants.MEETING_STATUS = meeting_status
    //Constants.MEETING_STATUS_ACTIVE = ACTIVE
    //Constants.MEETING_STATUS_INACTIVE = INACTIVE
    
    databaseReference0 = FirebaseDatabase.getInstance().getReference().child("meeting"); //is this correct
    databaseReference0.orderByChild(Constants.MEETING_STATUS).equalTo(Constants.MEETING_STATUS_ACTIVE).addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

            //MeetingModel getAllData = null;//wait, should i run it in debug mode
            //Log.i("printMeeting",getAllData.toString());
            for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {

                MeetingModel getAllData = dataSnapshot1.getValue(MeetingModel.class);
                arrayList.add(getAllData);
                Log.d("printMeeting",getAllData.toString());
            }

            if (arrayList.isEmpty()) {

            } else {

            }

        }

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

        }
    });
}

【问题讨论】:

  • Constants.MEETING_STATUS_ACTIVE 是什么类型?您将状态值保存为String
  • 首先,停止忽略错误。使用Log.d(TAG, error.getMessage());。您是否在 logcat 中打印了一些内容?除此之外,Constants.MEETING_STATUSConstants.MEETING_STATUS_ACTIVE 的值是多少?请回复@AlexMamo
  • 更新了问题。请帮帮我
  • 如果Constants.MEETING_STATUS_ACTIVE = "ACTIVE" 准确,您将不会得到任何结果,因为您在数据库中的会议状态是"0" 而不是"ACTIVE"
  • @AlexMamo ,没有错误。每次都会调用 onDataChanged 但只有 dataSnapshot 值为 null

标签: java android firebase firebase-realtime-database


【解决方案1】:

不建议更改全局变量,因为大多数 Firebase API 都是异步的,并且在您尝试使用它们时它们可能尚未初始化。例如,这个伪代码是行不通的。

// initialize...
getMeetingData()
// do something with arrayList now...

在某个位置获取数据时,返回的DataSnapshot 将包含您在顶层请求的数据。在某个位置执行查询时,返回的DataSnapshot 将包含您请求的数据作为其子项

// A Realtime Database FETCH
FirebaseDatabase.getInstance()
    .getReference()
    .child("meeting")
    .child(meetingId)
    .addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            if (!snapshot.exists()) {
                // TODO: Handle not-exists
                Log.i(TAG, "Requested meeting doesn\'t exist");
                return;
            }

            MeetingModel requestedModel = snapshot.getValue(MeetingModel.class);
            // TODO: do something with `requestedModel`
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
            // don't ignore this event, at least log it
            Log.e(TAG, "Failed to fetch data: " + databaseError.getMessage());
        }
    });
// A Realtime Database QUERY
FirebaseDatabase.getInstance()
    .getReference()
    .child("meeting")
    .orderByChild(Constants.MEETING_STATUS) // <-- becomes a query here
    .equalTo(Constants.MEETING_STATUS_ACTIVE)
    .addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot querySnapshot) {
            if (!querySnapshot.hasChildren()) {
                // TODO: Handle no matching data
                Log.i(TAG, "Requested query returned no results");
                return;
            }

            ArrayList<MeetingModel> matchingMeetings = new ArrayList<>();
            for (DataSnapshot meetingSnapshot : querySnapshot.getChildren()) {
                matchingMeetings.add(meetingSnapshot.getValue(MeetingModel.class));
            }

            // or, the simpler form:
            // GenericTypeIndicator<List<MeetingModel>> t = new GenericTypeIndicator<List<MeetingModel>>() {};
            // List<MeetingModel> matchingMeetings = snapshot.getValue(t);

            // TODO: do something with `matchingMeetings`
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
            // don't ignore this event, at least log it
            Log.e(TAG, "Failed to fetch data: " + databaseError.getMessage());
        }
    });

您也可以使用Task API:

private Task<List<MeetingModel>> getActiveMeetings() {
    return FirebaseDatabase.getInstance()
        .getReference()
        .child("meeting")
        .orderByChild(Constants.MEETING_STATUS)     // <-- becomes a query here
        .equalTo(Constants.MEETING_STATUS_ACTIVE)
        .get()                                      // <- fetch data from server
        .onSuccessTask(querySnapshot -> {           // <- mutate the returned data
            if (!querySnapshot.hasChildren()) {
                throw new DataNotFoundException();
            }

            GenericTypeIndicator<List<MeetingModel>> t = new GenericTypeIndicator<List<MeetingModel>>() {};
            return snapshot.getValue(t);
        });
}

那么当你需要使用它时:

getActiveMeetings()
    .addOnCompleteListener(task -> {
        if (task.isSuccessful()) {
            List<MeetingModel> meetings = task.getResult();
            // TODO: Handle
        } else {
            Exception ex = task.getException();
            // TODO: Handle
        }
    });

【讨论】:

  • 兄弟,在任务 api 中的 .get() 调用,它说“无法解析符号”
  • @Harsh0021 你确定你使用的是latest dependencies吗?
  • 兄弟,我没有使用 bom firebase api
  • 我必须使用它吗
  • 兄弟,您的答案无效,两种方法都试了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-21
  • 2020-08-05
  • 2018-03-15
  • 2018-12-11
  • 2019-03-08
相关资源
最近更新 更多