Я создаю новый проект, используя структуру базы данных Firebase в реальном времени.Моя база данных на самом деле выглядит так:
{
"questions" : {
"-LEFzp22FBk1PIKjL-Ov" : {
"description" : "Porque no quiere ",
"lastModification" : "05/06/2018 19:06:79",
"tags" : [ "Ingwe", "Dibujo" ],
"title" : "¿Por qué Ryu no me ayuda? ",
"userId" : "8LntU2FnnEe05XuSscMNJYGri0g2"
},
"-LEG3BE9kBTs5mm6T1QE" : {
"description" : "Descripción de la pregunta 2 ",
"lastModification" : "05/06/2018 19:06:66",
"tags" : [ "Pregunta", "Pregunta2" ],
"title" : "Pregunta 2",
"userId" : "8LntU2FnnEe05XuSscMNJYGri0g2"
}
},
"users" : {
"8LntU2FnnEe05XuSscMNJYGri0g2" : {
"id" : "8LntU2FnnEe05XuSscMNJYGri0g2",
"mail" : "ramon.guardialopez@gmail.com",
"name" : "ramon guardia",
"surname" : "",
"userName" : ""
}
}
}
Для каждого вопроса у меня есть свой идентификатор автора.
Мне нужно показать каждый вопрос, включая имя пользователя, поэтому я должен «искать» каждыйuser by userId для получения автора.
Мой адаптер:
package soulapps.codingfamily.ui.community;
import android.support.annotation.NonNull;
import android.support.design.chip.Chip;
import android.support.design.chip.ChipGroup;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.TextView;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import com.squareup.picasso.Picasso;
import org.w3c.dom.Text;
import java.util.ArrayList;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import de.hdodenhof.circleimageview.CircleImageView;
import soulapps.codingfamily.R;
import soulapps.codingfamily.data.model.Question;
import soulapps.codingfamily.data.model.User;
import static soulapps.codingfamily.Constants.DB_USERS_NODE;
public class CommunityAdapter extends FirebaseRecyclerAdapter<Question, CommunityAdapter.ViewHolder> {
// Vars
private OnItemClickListener onItemClickListener;
private List<Question> mData;
private DatabaseReference mPostReference;
/**
* Initialize a {@link RecyclerView.Adapter} that listens to a Firebase query. See
* {@link FirebaseRecyclerOptions} for configuration options.
*
* @param options
*/
public CommunityAdapter(@NonNull FirebaseRecyclerOptions<Question> options) {
super(options);
}
@Override
protected void onBindViewHolder(@NonNull CommunityAdapter.ViewHolder holder, int position, @NonNull Question model) {
holder.bind(model, position);
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(
R.layout.questions_list_item, parent, false);
final ViewHolder viewHolder = new ViewHolder(itemView);
itemView.setOnClickListener((View v) -> {
if (onItemClickListener != null) {
onItemClickListener.onItemClick(v, mData.get(viewHolder.getAdapterPosition()),
viewHolder.getAdapterPosition());
}
});
return viewHolder;
}
public class ViewHolder extends RecyclerView.ViewHolder {
// String array
ArrayList<String> tags;
// Firebase Question user
User questionUser;
// Question title var
@BindView(R.id.question_list_item_lblQuestionTitle)
TextView lblQuestionTitle;
// Question user name
@BindView(R.id.question_list_item_lblQuestionUserName)
TextView lblQuestionUserName;
// Question description
@BindView(R.id.question_list_item_lblQuestionDescription)
TextView lblQuestionDescription;
// Question creation
@BindView(R.id.question_list_item_lblQuestionCreation)
TextView lblQuestionCreation;
// Question chipGroup
@BindView(R.id.question_list_item_tagChipGroup)
ChipGroup tagChipGroup;
// Question user image
@BindView(R.id.profile_image)
CircleImageView profileImage;
public ViewHolder(@NonNull View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
//mDatabase = FirebaseDatabase.getInstance().getReference();
}
public void bind(Question question, int position) {
lblQuestionTitle.setText(question.getTitle());
lblQuestionDescription.setText(question.getDescription());
lblQuestionCreation.setText(question.getLastModification());
Picasso.get().load("https://imgur.com/a/aZ2C2WV").into(profileImage);
// TODO get the username from DB
// Get the user
FirebaseDatabase.getInstance().getReference().child(DB_USERS_NODE).child(question.getUserId())
.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Get user info
questionUser = dataSnapshot.getValue(User.class);
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
lblQuestionUserName.setText(questionUser.getName());
// Filling the array with all the question tags
tags = question.getTags();
// Create chips
for (String tag : tags) {
// For each tag in the array
// Creating a new chip
Chip chip = new Chip(lblQuestionCreation.getContext());
// Editing the chip data
chip.setText(tag);
// Add the chip to the chipGroup
tagChipGroup.addView(chip);
}
}
}
/*************************** INTERFACES ***************************/
@SuppressWarnings("unused")
public interface OnItemClickListener {
void onItemClick(View view, Question question, int position);
}
/*************************** INTERFACES ***************************/
}
На самом деле он не работает, потому что в документации firebase говорится, что событие onDataChange вызывается только каждый раз, когда данные изменяются, но янужны данные в начале загрузки приложения (никаких изменений не будет) - я не понимаю этого.
Я инициализирую и вызываю адаптер здесь:
package soulapps.codingfamily.ui.community;
import android.app.DownloadManager;
import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.google.firebase.database.Query;
import butterknife.BindView;
import butterknife.ButterKnife;
import soulapps.codingfamily.R;
import soulapps.codingfamily.data.QuestionRepository;
import soulapps.codingfamily.data.QuestionRepositoryImpl;
import soulapps.codingfamily.data.model.Question;
import soulapps.codingfamily.ui.main.MainActivityViewModel;
public class CommunityFragment extends Fragment{
private CommunityAdapter mAdapter;
private MainActivityViewModel mViewModel;
private QuestionRepository questionRepository;
private Query questionQuery;
@BindView(R.id.fragment_community_lstCommunity)
RecyclerView lstCommunity;
public CommunityFragment() {
}
public static CommunityFragment newInstance(){
return new CommunityFragment();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mViewModel = ViewModelProviders.of(getActivity()).get(MainActivityViewModel.class);
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
// TODO Sets emptyView
View view = inflater.inflate(R.layout.fragment_community, container, false);
questionRepository = QuestionRepositoryImpl.getInstance(getContext());
questionQuery = questionRepository.getLast50QuestionsQuery();
// Bind views
ButterKnife.bind(this, view);
// Sets mAdapter
FirebaseRecyclerOptions<Question> options =
new FirebaseRecyclerOptions.Builder<Question>()
.setQuery(questionQuery, Question.class)
.build();
mAdapter = new CommunityAdapter(options);
lstCommunity.setAdapter(mAdapter);
lstCommunity.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
lstCommunity.setItemAnimator(new DefaultItemAnimator());
lstCommunity.addItemDecoration(new DividerItemDecoration(inflater.getContext(), DividerItemDecoration.VERTICAL));
return view;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
@Override
public void onStart() {
super.onStart();
mAdapter.startListening();
}
@Override
public void onStop() {
super.onStop();
mAdapter.stopListening();
}
}
Как можноТогда я получаю пользовательские данные и правильно включаю их имя?
PS.Я использую FirebaseRecylcerAdapter (из FirebaseUi).