如何在Firebase中的多个节点中进行搜索

时间:2018-06-06 10:44:50

标签: android firebase firebase-realtime-database

我正在使用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" : ""
    }
  }
}

对于每个问题,我都包含了作者的ID。

要显示每个问题,包括用户名,所以我应该通过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)。

1 个答案:

答案 0 :(得分:3)

要解决此问题,您需要查询数据库两次,为此请使用以下代码:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference questionsRef = rootRef.child("questions");
Query query = questionsRef.orderByChild("userId").equalsTo(userId);
ValueEventListener valueEventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for(DataSnapshot ds : dataSnapshot.getChildren()) {
            String title = ds.child("title").getValue(String.class);

            DatabaseReference uidRef = rootRef.child("users").child(uid);
            ValueEventListener eventListener = new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    String userName = dataSnapshot.child("userName").getValue(String.class);
                    Log.d("TAG", title + " / " + userName);
                }

                @Override
                public void onCancelled(DatabaseError databaseError) {}
            };
            uidRef.addListenerForSingleValueEvent(eventListener);
        }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {}
};
questionsRef.addListenerForSingleValueEvent(valueEventListener);

其中userId是您要搜索问题的用户的ID。输出将是问题的标题和用户的用户名。