Shehara_r
Shehara_r

Reputation: 17

About retrieving nested data under Firebase auth Uid and pushed uid using andoid studio

I am creating a simple app using Android Studio and Firebase Realtime Database. When a user registered through the app, his data will be saved under Uid that firebase auth provides. Then I have created another node ( called PATH ) under this particular user to store his achievements. For this, I have pushed a key into that node and stored data under it.

This is the database structure I was talking about

Now I want to retrieve this data under PATH/pushedKey to a RecyclerView. But every time i run the code it gives null pointer exception to auth.getCurrentUser().getUid(). But the user is signed in already when this is called. I'm not matured in android studio or firebase but according to my knowledge if a user already signed in, then there must be something wrong with the database references I have put in the code. But I couldn't find anything. I tried many solutions from the site and google but nothing worked either. This is the part where I called the data.


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

And my adapter class to get more clear about this;

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

This is my 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;
    }
}

I really want some fresh eyes with better knowledge so if someone has any idea what I have done wrong here or what I can try to get this worked, you are very welcome here.

Upvotes: 0

Views: 170

Answers (1)

Alex Mamo
Alex Mamo

Reputation: 138824

The problem in your code lies in the fact that you have in your Model class a field named Achievement but you are using a getter named getAchievement(), which is not correct since Firebase is looking in the database for a field named achievement and not Achievement. See the lowercase a letter vs. capital letter A?

There are two ways in which you can solve this problem. The first one would be to change your model class by renaming the fields according to the Java Naming Conventions. So your model class should look like this:

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

See in this example, there are private fields and public getters. There is also a simpler solution, to set the value directly on public fields like this:

public class Model {
    public String achievment, date;
}

Now, just remove the current data and add it again using the correct names. This solution will work only if you are in the testing phase.

There is also the second approach, which is to use annotations. So if you prefer using private fields and public getters, you should use the PropertyName annotation only in front of the getters. So your Model class should look like this:

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

Upvotes: 1

Related Questions