# #android #firebase-realtime-database #android-recyclerview #firebaseui #android-viewholder
Вопрос:
Я пытаюсь создать систему комментариев для сообщений в моем приложении для социальных сетей. В моей базе данных у каждого поста есть раздел внутри таблицы «комментарии», например:
«гипно—######» — это название поста в социальных сетях. Он содержит комментарий, идентификатор пользователя, опубликовавшего комментарий, и метку времени, когда комментарий был опубликован. Каждый комментарий озаглавлен после того, как он был опубликован.
Это класс комментариев
public class comment { public String uID; public String comment_t; public long unixTimestamp; public comment() { // Default constructor required for calls to DataSnapshot.getValue(User.class) } public comment(String uID, String comment_t, long unixTimestamp) { this.uID = uID; this.comment_t = comment_t; this.unixTimestamp = unixTimestamp; } public String getuID() { return uID; } public void setuID(String uID) { this.uID = uID; } public String getComment() {return comment_t;} public void setComment() {this.comment_t = comment_t; } public long getUnixTimestamp() { return unixTimestamp; } }
Это адаптер для комментариев:
Public class Adapter_Comment extends FirebaseRecyclerAdapterlt;comment, Adapter_Comment.ViewHolder_comgt; { private DatabaseReference mDatabase; private static final String TAG = "RecyclerViewAdapter"; private Context mContext; FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser(); private static AppCompatActivity unwrap(Context context) { while (!(context instanceof Activity) amp;amp; context instanceof ContextWrapper) { context = ((ContextWrapper) context).getBaseContext(); } return (AppCompatActivity) context; } public Adapter_Comment(@NonNull FirebaseRecyclerOptionslt;commentgt; options) { super(options); //this.mContext = mContext; } @NonNull @Override public ViewHolder_com onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_comment, parent, false); mDatabase = FirebaseDatabase.getInstance().getReference(); return new ViewHolder_com(view); } @Override protected void onBindViewHolder(@NonNull ViewHolder_com holder, int position, @NonNull comment model) { mDatabase = FirebaseDatabase.getInstance().getReference(); long dv = model.getUnixTimestamp()*-1000; Date df = new java.util.Date(dv); String vv = new SimpleDateFormat("MM dd, yyyy hh:mma", Locale.ENGLISH).format(df); holder.time.setText(vv); String com = model.getComment(); holder.comment_text.setText(com); mDatabase.child("users").child(model.getuID()).child("profileUrl").addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { if (snapshot.exists()) { final String picUrl = snapshot.getValue(String.class); Glide.with(holder.postPfp.getContext()).load(picUrl).into(holder.postPfp); } } @Override public void onCancelled(@NonNull DatabaseError error) { } }); holder.postPfp.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //AppCompatActivity activity = (AppCompatActivity) v.getContext(); AppCompatActivity activity = unwrap(v.getContext()); Fragment OtherProfileFragment = new OtherProfileFragment(); Bundle bundle = new Bundle(); bundle.putString("key", model.getuID()); OtherProfileFragment.setArguments(bundle); activity.getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, OtherProfileFragment).addToBackStack(null).commit(); } }); } public class ViewHolder_com extends RecyclerView.ViewHolder { TextView comment_text; CircleImageView postPfp; TextView time; RelativeLayout comment_layout; public ViewHolder_com(@NonNull View itemView) { super(itemView); postPfp = itemView.findViewById(R.id.iv_comment_icon); comment_text = itemView.findViewById(R.id.tv_comment_text); time = itemView.findViewById(R.id.tv_comment_time); comment_layout = itemView.findViewById(R.id.comment_layout); } } }
This is Comment Fragment:
public class CommentFragment extends Fragment { private DatabaseReference mDatabase; FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser(); View view; String value; RecyclerView recyclerView; Query query; TextView comment_text; long unixTime = System.currentTimeMillis() / 1000L; public long globalUnix; Button comment_post; String comment_string; Adapter_Comment adapter; @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { view = inflater.inflate(R.layout.fragment_comment, container, false); value = getArguments().getString("key"); mDatabase = FirebaseDatabase.getInstance().getReference(); recyclerView = view.findViewById(R.id.recyclerv_comment); comment_text = view.findViewById(R.id.tv_comment_type); comment_post = view.findViewById(R.id.btn_comment_post); globalUnix = (unixTime * -1); comment_post.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(comment_text.getText().toString() == NULL){ Toast.makeText(getActivity(), "No Comment Typed", Toast.LENGTH_LONG).show(); } else{ comment com = new comment(); com.uID = user.getUid(); com.comment_t = comment_text.getText().toString(); com.unixTimestamp = globalUnix; mDatabase.child("comments").child(value).child(globalUnix "").setValue(com); } } }); initRecyclerView(); return view; } private void initRecyclerView(){ //Log.d(TAG, "initRecyclerView: init recyclerView"); LinearLayoutManager layoutManager = new LinearLayoutManager(getContext()); recyclerView.setLayoutManager(layoutManager); query = FirebaseDatabase.getInstance().getReference().child("comments").orderByValue(); FirebaseRecyclerOptionslt;commentgt; options = new FirebaseRecyclerOptions.Builderlt;commentgt;().setQuery(query, comment.class).build(); adapter = new Adapter_Comment(options); recyclerView.setAdapter(adapter); adapter.startListening(); adapter.notifyDataSetChanged(); } @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); } }
Внутри адаптера я использую модель комментариев, чтобы получить идентификатор, комментарий и метку времени для заполнения держателя, однако, когда я устанавливаю эти значения, я получаю нулевые значения. Есть ли что-то, чего мне не хватает при попытке подключить адаптер/firebase и модель/держатель?
long dv = model.getUnixTimestamp()*-1000; Date df = new java.util.Date(dv); String vv = new SimpleDateFormat("MM dd, yyyy hh:mma", Locale.ENGLISH).format(df); holder.time.setText(vv); String com = model.getComment(); holder.comment_text.setText(com); mDatabase.child("users").child(model.getuID()).child("profileUrl").addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { if (snapshot.exists()) { final String picUrl = snapshot.getValue(String.class); Glide.with(holder.postPfp.getContext()).load(picUrl).into(holder.postPfp); } } @Override public void onCancelled(@NonNull DatabaseError error) { } });
Ответ №1:
Здесь действительно слишком много всего происходит, но…
Насколько я вижу, вы создаете адаптер FirebaseUI FirebaseDatabase.getInstance().getReference().child("comments")
. Адаптеры FirebaseUI показывают прямые дочерние узлы узла, в который вы входите, поэтому в вашем случае для узла будет создано одно представление hypno---...196
. Вы пытаетесь прочитать Comment
объект оттуда, но он не существует до тех пор, пока в вашем JSON не будет на один уровень ниже.
Так что вы можете:
- Либо покажите комментарии к одному сообщению, основываясь на этом адаптере. Итак:
FirebaseDatabase.getInstance().getReference().child("comments").child("hypno---...196")
(какой там настоящий ключ). - Или вы можете показать одну часть информации о каждом посте, например, его ключ.
Если вы хотите отобразить единый список комментариев для всех сообщений через адаптер FirebaseUI, вам также придется сохранить единый список комментариев для всех сообщений в вашей базе данных.