简体   繁体   English

无法获得孩子的 arraylist (firebase)

[英]Having troubles getting arraylist of a child (firebase)

Hi everyone I am trying to retrieve data from firebase and display them based on what I clicked on RecyclerView and pass the name to the next activity.大家好我正在尝试从 firebase 检索数据并根据我在 RecyclerView 上单击的内容显示它们并将名称传递给下一个活动。

Whenever I tried to do this it would always close the app and opens again.每当我尝试这样做时,它总是会关闭应用程序并再次打开。

But whenever there is no "Dates_Log_In" in the collection it would run but doesn't display any kind of data.但是只要集合中没有“Dates_Log_In”,它就会运行但不显示任何类型的数据。

this is the class that I use for displaying all data in the RecyclerView这是我用来在 RecyclerView 中显示所有数据的 class

public class Listing extends AppCompatActivity implements AttendanceListAdapter.OnNoteListener{

    Button back;
    DatabaseReference mRef;

    ArrayList<Attendance> userList;
    RecyclerView recyclerView;
    AttendanceListAdapter adapter;

    TextView name;
    TextView designation;
    TextView activity;
    TextView status;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.list);

        recyclerView = findViewById(R.id.rcl_List);
        back = findViewById(R.id.btn_go_back);
        name = findViewById(R.id.txt_name1);
        designation = findViewById(R.id.txt_designation1);
        activity = findViewById(R.id.txt_activity1);
        status = findViewById(R.id.txt_status1);

        mRef = FirebaseDatabase.getInstance().getReference("Users");

        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));

        userList = new ArrayList<>();
        adapter = new AttendanceListAdapter(this, userList);
        recyclerView.setAdapter(adapter);

        mRef.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                for(DataSnapshot dataSnapshot : snapshot.getChildren()){

                    Attendance user = dataSnapshot.getValue(Attendance.class);
                    userList.add(user);
                }
                adapter.notifyDataSetChanged();
            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {
                Toast.makeText(Listing.this, "Failed to retrieve Data", Toast.LENGTH_LONG).show();
            }
        });

        back.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finish();
            }
        });
    }

    @Override
    public void onNoteClick(int position) {
        userList.get(position);

    }
}

Attendance Class考勤 Class

public class Attendance {

    public String fullname, designation, activity, status, date;

    private long maxid = 0;

    private DatabaseReference mref;
    public Attendance(){

    }
    public Attendance(String fullname, String designation, String activity, String status){

        this.fullname = fullname;
        this.designation = designation;
        this.activity = activity;
        this.status = status;
    }

    public void setFullname(String fullname) {
        this.fullname = fullname;
    }

    public void setDesignation(String designation) {
        this.designation = designation;
    }

    public void setActivity(String activity) {
        this.activity = activity;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public String getFullname(){
        return fullname;
    }
    public String getDesignation(){
        return designation;
    }
    public String getActivity(){
        return activity;
    }
    public String getStatus(){
        return status;
    }
    public String getDate(){
        return date;
    }
}

AttendanceListAdapter考勤表适配器

public class AttendanceListAdapter extends RecyclerView.Adapter<AttendanceListAdapter.MyViewHolder> {

    ArrayList<Attendance> attendanceArrayList;
    Context context;

    public AttendanceListAdapter(Context context, ArrayList<Attendance> list){
        this.context = context;
        this.attendanceArrayList = list;
    }

    public class MyViewHolder extends RecyclerView.ViewHolder {
        private TextView name, designation, activity, status;

        public MyViewHolder(final View view){
            super(view);
            name = view.findViewById(R.id.txt_name1);
            designation = view.findViewById(R.id.txt_designation1);
            activity = view.findViewById(R.id.txt_activity1);
            status = view.findViewById(R.id.txt_status1);
        }
    }

    @NonNull
    @Override
    public AttendanceListAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_layout, parent, false);
        return new MyViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull AttendanceListAdapter.MyViewHolder holder, int position) {

        Attendance user = attendanceArrayList.get(position);

        holder.name.setText(user.getFullname());
        holder.designation.setText(user.getDesignation());
        holder.activity.setText(user.getActivity());
        holder.status.setText(user.getStatus());
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String id = user.getFullname();
                passData(id);

            }
        });

    }

    private void passData(String id) {

        Intent intent = new Intent(context,Logbook.class);
        intent.putExtra("id", id);
        context.startActivity(intent);
    }

    @Override
    public int getItemCount() {
        return attendanceArrayList.size();
    }

    public interface OnNoteListener{
        void onNoteClick(int position);
    }

}

And this is where I pass the data and it should display the "Dates_Log_In" to a ListView (not quiet sure if this is the right choice)这是我传递数据的地方,它应该将“Dates_Log_In”显示到 ListView(不确定这是否是正确的选择)

public class Logbook extends AppCompatActivity {

    Button back;
    DatabaseReference mRef;
    ListView listView;
    ArrayList<String> userList;
    ArrayAdapter<String> adapter;
    TextView txt_name;
    TextView txt_date;

    date Date;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_logbook);

        Intent intent = getIntent();
        String id = intent.getStringExtra("id");

        Date = new date();

        listView = findViewById(R.id.list_date);
        back = findViewById(R.id.btn_go_back2);
        txt_name = findViewById(R.id.txt_nameselected);
        txt_date = findViewById(R.id.txt_date);
        txt_name.setText(id);

        mRef = FirebaseDatabase.getInstance().getReference("Users").child(id);
        userList = new ArrayList<>();
        adapter = new ArrayAdapter<String>(this, R.layout.logbook_layout, R.id.txt_date, userList);

        mRef.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                for(DataSnapshot dataSnapshot : snapshot.getChildren()){
                    Log.i("Dates_Log_In", dataSnapshot.getValue(String.class));
                    Date = dataSnapshot.getValue(date.class);
                    userList.add(Date.getDate());
                }
                listView.setAdapter(adapter);
            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {
                Toast.makeText(Logbook.this, "Failed to retrieve Data", Toast.LENGTH_LONG).show();
            }
        });

        back.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finish();
            }
        });

During the test run the error gives as it follows在测试运行期间,错误给出如下

E/le.enrollmentq: [qarth_debug:]  get PatchStore::createDisableExceptionQarthFile method fail.
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.enrollmentqr, PID: 3144
    com.google.firebase.database.DatabaseException: Failed to convert value of type java.util.ArrayList to String
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertString(CustomClassMapper.java:426)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(CustomClassMapper.java:217)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertToCustomClass(CustomClassMapper.java:80)
        at com.google.firebase.database.DataSnapshot.getValue(DataSnapshot.java:203)
        at com.example.enrollmentqr.Logbook$1.onDataChange(Logbook.java:64)
        at com.google.firebase.database.core.ValueEventRegistration.fireEvent(ValueEventRegistration.java:75)
        at com.google.firebase.database.core.view.DataEvent.fire(DataEvent.java:63)
        at com.google.firebase.database.core.view.EventRaiser$1.run(EventRaiser.java:55)
        at android.os.Handler.handleCallback(Handler.java:907)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:216)
        at android.app.ActivityThread.main(ActivityThread.java:7625)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)

and in the logcat this shows在 logcat 中显示

2022-05-05 22:33:21.684 3144-3144/com.example.enrollmentqr W/ClassMapper: No setter/field for Dates_Log_In found on class com.example.enrollmentqr.Attendance
2022-05-05 22:33:21.700 3144-3144/com.example.enrollmentqr W/ClassMapper: No setter/field for Dates_Log_In found on class com.example.enrollmentqr.Attendance

This is the rules I set for the database.这是我为数据库设置的规则。

{
  "rules": {
    ".read": true,
    ".write": true,
    "Users": {
        "Dates_Log_In":{
          "$uid":{
          ".read": true,
          ".write": true,
          }
        },
        "activity":{
        ".read": true,
        ".write": true,
        },
        "designation":{
        ".read": true,
        ".write": true,
        },
        "fullname":{
        ".read": true,
        ".write": true,
        },
        "status":{
        ".read": true,
        ".write": true,
        }
    }
  }
}

I kinda know while fetching the data from the firebase because i didnt include the date on the Attendance.class thats why it is giving a null value (just my hunch).我有点知道从 firebase 获取数据是因为我没有在 Attendance 上包含日期。class 这就是为什么它给出 null 值(只是我的直觉)。 So I tried including it but that also didnt work out for me.所以我尝试包括它,但这对我来说也没有用。 Im kinda guessing that there is something wrong on how i call the firebase?我有点猜测我如何称呼 firebase 有问题? I just started just a few days ago and doing this for my project.我几天前才开始为我的项目做这件事。

This makes no sense:这没有意义:

Log.i("Dates_Log_In", dataSnapshot.getValue(String.class));
Date = dataSnapshot.getValue(date.class);

The dataSnapshot can be a String or it can be a date , but it can never be both at the same time. dataSnapshot可以是String也可以是date ,但不能同时是两者。 That means at least one of these lines will always fail.这意味着这些行中至少有一条总是会失败。


Since you are reading this path:由于您正在阅读此路径:

mRef = FirebaseDatabase.getInstance().getReference("Users").child(id);

So you are reading from /Users/$id , which as far as I can tell contains the data for a single user.因此,您正在阅读/Users/$id ,据我所知,它包含单个用户的数据。 That means you don't need to loop over snapshot.getChildren in your onDataChange , since the snapshot already contains just the data for that single user.这意味着您不需要在onDataChange中遍历snapshot.getChildren ,因为snapshot已经只包含该单个用户的数据。

Then there's the matter of data under there, which is hard to determine without seeing your actual JSON. The safest I can recommend is to just let Firebase figure it out, and call getValue() without a type.然后是那里的数据问题,如果没有看到您的实际 JSON 就很难确定。我可以推荐的最安全的方法是让 Firebase 弄清楚,然后调用没有类型的getValue()

mRef.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot snapshot) {
        Map<String, object> values = dataSnapshot.getValue();
        ...
    }

Most likely you'll get back a Map<String, Object> from that, which you can then show with something like this: How to print all key and values from HashMap in Android?您很可能会从中得到一个Map<String, Object> ,然后您可以用这样的东西来显示它: How to print all key and values from HashMap in Android?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM