无法使用Firebase实时数据库过滤包含多个子句的查询

时间:2018-05-20 01:02:58

标签: java android firebase firebase-realtime-database firebaseui

我使用Firebase实时数据库和Firebase用户界面,但是我无法使用多个子句进行搜索。

我需要的是采取没有特定ID的用户。由于我已经按城市过滤它们,我需要使用特定ID过滤这些过滤器。 我一直试图以多种方式解决它,但是没有一个能够取得成功。

这是我的数据库

enter image description here

我无法使用该用户名与用户一起呈现卡片。

public class SearchFragment extends android.support.v4.app.Fragment {


    private EditText mSearchField;
    private ImageButton mSearchBtn;
    private RecyclerView mResultList;
    private DatabaseReference mUserDatabase;

    public static SearchFragment newInstance() { return new SearchFragment();  }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_search, container, false);
        mSearchField = view.findViewById(R.id.search_field);
        mSearchBtn = view.findViewById(R.id.search_btn);

        mResultList = view.findViewById(R.id.result_list);
        mResultList.setHasFixedSize(true);
        mResultList.setLayoutManager(new LinearLayoutManager(mResultList.getContext()));

        mSearchBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String searchText = mSearchField.getText().toString();
                firebaseUserSearch(searchText);
                mSearchField.setText("");
            }
        });

        mUserDatabase = FirebaseDatabase.getInstance().getReference("usuarios");
        return view;
    }

    public void firebaseUserSearch(String searchText) {
        Toast.makeText(getContext(), "Buscando usuários", Toast.LENGTH_LONG).show();

        String searchTextLower = searchText.toLowerCase();

        final Query firebaseSearchQuery = mUserDatabase.orderByChild("city").startAt(searchTextLower).endAt(searchTextLower + "\uf8ff");

        firebaseSearchQuery.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                GenericTypeIndicator<Map<String, String>> genericTypeIndicator = new GenericTypeIndicator<Map<String, String>>() {};
                Map<String, String> map = dataSnapshot.getValue(genericTypeIndicator );
                String username = map.get("username").toString();
                Log.d("oi", username);
                Log.d("olar", UserDetails.username);

                if(username != UserDetails.username) {
                    final FirebaseRecyclerOptions<User> options =
                            new FirebaseRecyclerOptions.Builder<User>()
                                    .setQuery(firebaseSearchQuery, User.class)
                                    .build();
                    bindAndBuildFirebaseUi(options);
                }
            }



    public void bindAndBuildFirebaseUi(FirebaseRecyclerOptions options) {
        final FirebaseRecyclerAdapter<User, UsersViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<User, UsersViewHolder>(options) {
            @Override
            public UsersViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
                View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_layout, parent, false);
                return new UsersViewHolder(v);
            }

            @Override
            protected void onBindViewHolder(final UsersViewHolder holder, int position, final User model) {
                holder.bind(model);
                Log.d("SearchFragment", "Binded the model");
                holder.itemView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        UserDetails.chatWithId = model.getUsername();
                        UserDetails.chatWith = model.getName();
                        startActivity(new Intent(getContext(), Chat.class));
                    }
                });
            }
        };
        firebaseRecyclerAdapter.startListening();
        mResultList.setAdapter(firebaseRecyclerAdapter);
    }
}

正如你所看到的,我甚至试图再次通过数据库过滤它们,然而,Firebase ui正在从选项中获取过滤器,这是第一个按城市过滤用户的查询。

有没有人知道如何避免呈现具有特定ID的用户???

我也知道Firebase不允许使用多个订单。

1 个答案:

答案 0 :(得分:0)

不幸的是,Firebase RTDB doesn't support multiple where clauses。但是,如果正确地对数据进行非规范化,则可以使用一个查询链接到数据库中的另一个ref,并以这种方式有效地过滤数据。请查看文档:{​​{3}}。

作为旁注,您实际上不应该使用RTDB来存储实际数据,因为它无法扩展。它专为多人游戏或票务应用程序等的低延迟实时更新而设计。相反,我建议调查https://github.com/firebase/FirebaseUI-Android/blob/master/database/README.md#using-firebaseui-with-indexed-data,特别是如果这是一个新的应用程序。

以下是我在下面的评论中提到的黑客攻击:

public class MyAdapter extends FirebaseRecyclerAdapter {
    private static final int TYPE_NORMAL = 0;
    private static final int TYPE_HIDDEN = 1;

    private final View mEmpty = new View(getContext());

    public MyAdapter(@NonNull FirestoreRecyclerOptions options) {
        super(options);
        mEmpty.setVisibility(View.GONE);
    }

    @Override
    public int getItemViewType(int position) {
        if (getItem(position).username.equals(UserDetails.username)) {
            return TYPE_HIDDEN;
        } else {
            return TYPE_NORMAL;
        }
    }

    @Override
    public UsersViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == TYPE_HIDDEN) {
            return new UsersViewHolder(mEmpty);
        }

        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_layout, parent, false);
        return new UsersViewHolder(v);
    }

    @Override
    protected void onBindViewHolder(final UsersViewHolder holder, int position, final User model) {
        if (getItemViewType(position) == TYPE_HIDDEN) return;

        holder.bind(model);
        Log.d("SearchFragment", "Binded the model");
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                UserDetails.chatWithId = model.getUsername();
                UserDetails.chatWith = model.getName();
                startActivity(new Intent(getContext(), Chat.class));
            }
        });
    }
}