尝试从Firebase获取密钥,而不是获取奇怪的路径

时间:2018-09-16 16:24:36

标签: java android firebase firebase-realtime-database

我有一个这样的数据库结构:

"users": {
   "school": {
      userId (randomkey) {
         "email": "email@emai.email"
         "provider": "provider"
      }
   }
}

我正在使用一个回收站视图,用户可以在其中将彼此添加到组中。我在“回收者”视图中显示给用户的电子邮件,效果很好。但是问题是我需要检索所单击电子邮件的userId密钥,并将其附加到列表中,然后将其推送到firebase。我正在用这段代码来做所有的事情。

适配器类

    class RecyclerViewHolder extends RecyclerView.ViewHolder implements  View.OnClickListener {

    private ItemClickListenerPeopleToAdd itemClickListenerPeopleToAdd;
    public TextView emailLbl;

    public RecyclerViewHolder(View itemView) {
        super(itemView);
        itemView.setOnClickListener(this);
        emailLbl = (TextView) itemView.findViewById(R.id.emailLbl);
    }

    public void setItemClickListenerPeopleToAdd(ItemClickListenerPeopleToAdd itemClickListenerPeopleToAdd) {
        this.itemClickListenerPeopleToAdd = itemClickListenerPeopleToAdd;
    }

    @Override
    public void onClick(View v) {

        itemClickListenerPeopleToAdd.onClick(v, getAdapterPosition());
    }
}

public class PeopleToAddAdapter extends RecyclerView.Adapter<RecyclerViewHolder> {
    private static final String TAG = "Working";
    public ArrayList<String> peopleList = new ArrayList<String>();
    private List<ModelProject> mModelList;

    public PeopleToAddAdapter(List<ModelProject> modelList) {
        mModelList = modelList;
    }

    private Context context;
    private List<PeopleToAdd> mPeopleToAdd;
    public List<PeopleToAdd> mList;


    public PeopleToAddAdapter(Context con, List<PeopleToAdd> list) {
        this.context = con;
        this.mPeopleToAdd = list;
    }

    @NonNull
    @Override
    public RecyclerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.people_to_add_listview, parent, false);

        return new RecyclerViewHolder(v);
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerViewHolder holder, int position) {

        final PeopleToAdd listItem = mPeopleToAdd.get(position);
        holder.emailLbl.setText(listItem.getEmail());
        holder.setItemClickListenerPeopleToAdd(new ItemClickListenerPeopleToAdd() {
            @Override
            public void onClick(View view, int position) {
                Toast.makeText(context, "Click" + listItem.getEmail(), Toast.LENGTH_SHORT).show();
                peopleList.add(listItem.toString());
                Log.d("value", String.valueOf(peopleList));
            }
        });
    }

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

    public class MyViewHolder extends RecyclerView.ViewHolder {
        public TextView emailLbl;

        public MyViewHolder(View itemView) {
            super(itemView);
            emailLbl = (TextView) itemView.findViewById(R.id.emailLbl);
        }
    }
}

PeopleToAdd

public class PeopleToAdd {
private String email;
private String provider;

public PeopleToAdd(String email, String provider) {
    this.email = email;
    this.provider = provider;
}

public PeopleToAdd() {

}

public String getEmail() {
    return email;
}

public void setEmail(String email) {
    this.email = email;
}

public String getProvider() {
    return provider;
}

public void setProvider(String provider) {
    this.provider = provider;
}

}

活动类

listItems = new ArrayList<>();
    schoolList = new ArrayList<>();

    adapter = new PeopleToAddAdapter(this, listItems);
    recyclerView.setAdapter(adapter);

    mGetSchool = mDatabase.getReference().child("users").child(mCurrentUserId).child("schoolName");

protected void onStart() {
    super.onStart();

    mGetSchool.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            childPath = dataSnapshot.getValue(String.class);
            //peopleAddedTxtView.setText(childPath);
            mPeopleToAdd = mDatabase.getReference().child("users").child(childPath);

            mPeopleToAdd.addChildEventListener(new ChildEventListener() {
                @Override
                public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

                    PeopleToAdd peopleToAdd = dataSnapshot.getValue(PeopleToAdd.class);
                    listItems.add(peopleToAdd);

                    test = dataSnapshot.getKey();
                    Log.d(TAG, test);
                    peopleToAddAdapter = new PeopleToAddAdapter(SetProject.this, listItems);
                    recyclerView.setAdapter(peopleToAddAdapter);
                    peopleToAddAdapter.notifyDataSetChanged();
                }

                @Override
                public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

                }

                @Override
                public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {

                }

                @Override
                public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

                }

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

                }
            });
        }

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

        }
    });
}

我以某种方式获得了一条奇怪的路径作为用户ID 例如:“ com.appName.Services.PeopleToAdd@ca8f01”。如何获得正确的userId(firebase生成的随机密钥)。我将它放在活动的“测试”字符串中,但是当用户在reyclerView中单击该用户时,如何将其添加到列表中。我希望你能理解我。先感谢您。

1 个答案:

答案 0 :(得分:0)

快照包含两个主要内容:从中加载数据的键和已加载的值。现在,您的onChildAdded仅使用该值,并丢掉了键:

public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

    PeopleToAdd peopleToAdd = dataSnapshot.getValue(PeopleToAdd.class);
    listItems.add(peopleToAdd);

    test = dataSnapshot.getKey();
    Log.d(TAG, test);
    peopleToAddAdapter = new PeopleToAddAdapter(SetProject.this, listItems);
    recyclerView.setAdapter(peopleToAddAdapter);
    peopleToAddAdapter.notifyDataSetChanged();
}

并且由于您稍后在代码中需要密钥,因此无法再检索它。该值不包含键。

一种解决方案是将密钥添加到您的PeopleToAdd类中。根据我对Is there a way to store Key in class which I cast from Firebase object?的回答,对您来说,看起来像这样:

public class PeopleToAdd {
    @Exclude
    public String key;

    private String email;
    private String provider;

    public PeopleToAdd(String email, String provider) {
        this.email = email;
        this.provider = provider;
    }

    public PeopleToAdd() {

    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getProvider() {
        return provider;
    }

    public void setProvider(String provider) {
        this.provider = provider;
    }
}

然后修改您的onChildAdded来设置从值实例化的PeopleToAdd上的密钥:

public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

    PeopleToAdd peopleToAdd = dataSnapshot.getValue(PeopleToAdd.class);

    peopleToAdd.key = dataSnapshot.getKey();

    listItems.add(peopleToAdd);

    peopleToAddAdapter = new PeopleToAddAdapter(SetProject.this, listItems);
    recyclerView.setAdapter(peopleToAddAdapter);
    peopleToAddAdapter.notifyDataSetChanged();
}

现在,您可以从其PeopleToAdd字段中获取key的密钥。