【问题标题】:About retrieving nested data under Firebase auth Uid and pushed uid using andoid studio关于在Firebase auth Uid下检索嵌套数据并使用android studio推送uid
【发布时间】:2021-10-01 05:24:22
【问题描述】:

我正在使用 Android Studio 和 Firebase 实时数据库创建一个简单的应用程序。当用户通过应用注册时,他的数据将保存在 firebase auth 提供的 Uid 下。 然后我在这个特定用户下创建了另一个节点(称为 PATH )来存储他的成就。为此,我已将一个密钥推入该节点并在其下存储数据。

现在我想将 PATH/pushedKey 下的这些数据检索到 RecyclerView。但是每次我运行代码时,它都会给 auth.getCurrentUser().getUid() 提供空指针异常。但是在调用它时用户已经登录。我在 android studio 或 firebase 方面并不成熟,但据我所知,如果用户已经登录,那么我在代码中放入的数据库引用一定有问题。但我什么也找不到。我从网站和谷歌尝试了许多解决方案,但也没有任何效果。 这是我调用数据的部分。


        reference = FirebaseDatabase.getInstance().getReference();
        user_reference = reference.child("users");
        path_reference = user_reference.child(auth.getCurrentUser().getUid()).child("PATH");

        auth = FirebaseAuth.getInstance();

        recyclerView = findViewById(R.id.recycler_path);

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

        arrayList = new ArrayList<>();
        path_adapter = new PATH_Adapter(this, arrayList);
        recyclerView.setAdapter(path_adapter);

        path_reference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {

                    for (DataSnapshot key : snapshot.getChildren()) {

                            Model model = key.getValue(Model.class);
                            arrayList.add(model);

                            path_adapter.notifyDataSetChanged();
                            Log.d(TAG, user_id);
                    }
            }

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

                Log.v(TAG, error.getMessage());
            }
        });

还有我的适配器类可以更清楚地了解这一点;

public class PATH_Adapter extends RecyclerView.Adapter<PATH_Adapter.PViewHolder> {

    Context context;
    ArrayList<Model> arrayList;

    public PATH_Adapter(Context context, ArrayList<Model> arrayList){
        this.context = context;
        this.arrayList = arrayList;
    }

    @NonNull
    @Override
    public PATH_Adapter.PViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        View v = LayoutInflater.from(context).inflate(R.layout.path_list, parent, false);
        return new PViewHolder(v);
    }

    @Override
    public void onBindViewHolder(@NonNull PATH_Adapter.PViewHolder holder, int position) {

        String achie = arrayList.get(position).getAchievement();
        String date = arrayList.get(position).getDate();

        holder.setAch( achie, date);
    }

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

    public class PViewHolder extends RecyclerView.ViewHolder{

        private TextView achievement, dates;

        public PViewHolder(@NonNull View itemView) {
            super(itemView);

            achievement = itemView.findViewById(R.id.achievement);
            dates = itemView.findViewById(R.id.date);
        }

        public void setAch( String achie, String date){
            achievement.setText(achie);
            dates.setText(date);
        }
    }
}

这是我的 Model.class,

public class Model {

    String Achievement, Date;

    public Model(String achievment, String date) {

        this.Achievement = achievment;
        this.Date = date;
    }

    public String getAchievement() {
        return Achievement;
    }

    public void setAchievement(String achievment) {
        this.Achievement = achievment;
    }

    public String getDate() {
        return Date;
    }

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

我真的想要一些新的眼睛和更好的知识,所以如果有人知道我在这里做错了什么或者我可以尝试什么来解决这个问题,非常欢迎你在这里。

【问题讨论】:

  • 请编辑您的问题并添加您的Model课程的内容。
  • @AlexMamo 模型类已添加。

标签: java android firebase firebase-realtime-database android-recyclerview


【解决方案1】:

代码中的问题在于,您在 Model 类中有一个名为 Achievement 的字段,但您使用的是名为 getAchievement() 的 getter,这是 正确的,因为Firebase 正在数据库中查找名为 achievementnot Achievement 的字段。看到小写的a 和大写的A

有两种方法可以解决这个问题。第一个是通过根据Java Naming Conventions 重命名字段来更改您的模型类。所以你的模型类应该是这样的:

public class Model {
    private String achievment, date;

    public Model(String achievment, String date) {
        this.achievment = achievment;
        this.date = date;
    }

    public String getAchievement() {
        return achievment;
    }

    public void setAchievement(String achievment) {
        this.achievment = achievment;
    }

    public String getDate() {
        return date;
    }

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

在这个例子中,有private 字段和公共getter。还有一个更简单的解决方案,直接在公共字段上设置值,如下所示:

public class Model {
    public String achievment, date;
}

现在,只需删除当前数据并使用正确的名称再次添加即可。此解决方案仅在您处于测试阶段时才有效。

还有第二种方法,就是使用annotations。因此,如果您更喜欢使用私有字段和公共 getter,则应仅在 getter 前面使用 PropertyName 注释。所以你的Model 类应该是这样的:

public class Model {
    private String achievment, date;

    public Model(String achievment, String date) {
        this.achievment = achievment;
        this.date = date;
    }

    @PropertyName("Achievement")
    public String getAchievement() {
        return achievment;
    }

    public void setAchievement(String achievment) {
        this.achievment = achievment;
    }

    @PropertyName("Date")
    public String getDate() {
        return date;
    }

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

【讨论】:

  • 感谢您的回答。这个命名错误是我有史以来最严重的错误之一。我还在学习android studio。这是我大学的一个项目。你的回答对我帮助很大。
  • 我照你说的做了。现在应用程序没有崩溃。但是回收站列表中没有显示任何数据。只有空项目。有什么你认为我应该尝试让它发挥作用的吗?
  • 很遗憾,没有看到更改后的代码,我帮不上什么忙。因此,我建议您在 StackOverflow 上使用自己的 MCVE 发布一个新问题,以便我和其他 Firebase 开发人员可以为您提供帮助。
  • 好的,我会尝试更多,如果我没有成功,我会添加一个问题。再次感谢您的支持..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-30
  • 2019-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多