首页 > 解决方案 > 当我向其添加查询时,addListenerForSingleValueEvent 返回 dataSnapshot 值 null

问题描述

我正在做一个安卓项目。有一个与 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) {

        }
    });
}

在此处输入图像描述

标签: javaandroidfirebasefirebase-realtime-database

解决方案


不建议更改全局变量,因为大多数 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());
        }
    });

您还可以使用TaskAPI:

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

推荐阅读