Firebase 实时数据库在查询之间按单词搜索? [英] Firebase Realtime Database Search by word in between the query?

查看:23
本文介绍了Firebase 实时数据库在查询之间按单词搜索?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序中,我在 Firebase 中有一个实时数据库,其中包含标题、图像、描述、搜索(应用程序中未显示的额外字段,但使用包含带有小写字母的标题文本以进行搜索不敏感).目前,当我在小写或大写或两者混合时输入相同的查询时,它搜索完美,但是当我输入查询之间的某个单词时,它不起作用例如,如果查询是This is longtitle" 当我输入long"时它什么也没显示.我被困在帮他解决这个问题.

我使用了

这是我的活动代码:

package com.blogspot.atifsoftwares.firebaseproject;导入 android.content.DialogInterface;导入 android.content.Intent;导入 android.content.SharedPreferences;导入 android.graphics.Bitmap;导入 android.graphics.drawable.BitmapDrawable;导入 android.graphics.drawable.Drawable;导入 android.support.annotation.NonNull;导入 android.support.v4.view.MenuItemCompat;导入 android.support.v7.app.ActionBar;导入 android.support.v7.app.AlertDialog;导入 android.support.v7.app.AppCompatActivity;导入 android.os.Bundle;导入 android.support.v7.widget.LinearLayoutManager;导入 android.support.v7.widget.RecyclerView;导入 android.support.v7.widget.SearchView;导入 android.view.LayoutInflater;导入 android.view.Menu;导入 android.view.MenuItem;导入 android.view.View;导入 android.view.ViewGroup;导入 android.widget.ImageView;导入 android.widget.TextView;导入 com.firebase.ui.database.FirebaseRecyclerAdapter;导入 com.firebase.ui.database.FirebaseRecyclerOptions;导入 com.google.firebase.database.DatabaseReference;导入 com.google.firebase.database.FirebaseDatabase;导入 com.google.firebase.database.Query;导入 java.io.ByteArrayOutputStream;公共类 PostsListActivity 扩展 AppCompatActivity {LinearLayoutManager mLayoutManager;//用于排序SharedPreferences mSharedPref;//用于保存排序设置RecyclerView mRecyclerView;FirebaseDatabase mFirebaseDatabase;数据库参考 mRef;FirebaseRecyclerAdapterfirebaseRecyclerAdapter;FirebaseRecyclerOptions<模型>选项;@覆盖protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_posts_list);//动作条ActionBar actionBar = getSupportActionBar();//设置标题mSharedPref = getSharedPreferences("SortSettings", MODE_PRIVATE);String mSorting = mSharedPref.getString("Sort", "newest");//如果没有选择设置,最新的将是默认的如果(mSorting.equals(最新")){mLayoutManager = new LinearLayoutManager(this);//这将从底部加载项目意味着最新的首先mLayoutManager.setReverseLayout(true);mLayoutManager.setStackFromEnd(true);} else if (mSorting.equals("oldest")) {mLayoutManager = new LinearLayoutManager(this);//这将从底部加载项目意味着最旧的首先mLayoutManager.setReverseLayout(false);mLayoutManager.setStackFromEnd(false);}//回收器视图mRecyclerView = findViewById(R.id.recyclerView);mRecyclerView.setHasFixedSize(true);//向 FirebaseDatabase 发送查询mFirebaseDatabase = FirebaseDatabase.getInstance();mRef = mFirebaseDatabase.getReference("数据");显示数据();}//显示数据私有无效 showData(){options = new FirebaseRecyclerOptions.Builder().setQuery(mRef, Model.class).build();firebaseRecyclerAdapter = new FirebaseRecyclerAdapter(options) {@覆盖protected void onBindViewHolder(@NonNull ViewHolder holder, int position, @NonNull Model model) {holder.setDetails(getApplicationContext(),model.getTitle(),model.getDescription(),model.getImage());}@非空@覆盖public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {//膨胀布局row.xml查看 itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row, parent, false);ViewHolder viewHolder = new ViewHolder(itemView);//项目点击监听器viewHolder.setOnClickListener(new ViewHolder.ClickListener() {@覆盖public void onItemClick(View view, int position) {//在点击的位置从firebase获取数据String mTitle = getItem(position).getTitle();String mDesc = getItem(position).getDescription();String mImage = getItem(position).getImage();//将此数据传递给新活动Intent intent = new Intent(view.getContext(), PostDetailActivity.class);intent.putExtra("title", mTitle);//输入标题intent.putExtra("描述", mDesc);//输入描述intent.putExtra("image", mImage);//输入图片地址开始活动(意图);//开始活动}@覆盖public void onItemLongClick(View view, int position) {//Todo在这里实现你的长按功能}});返回 viewHolder;}};//设置布局为LinearLayoutmRecyclerView.setLayoutManager(mLayoutManager);firebaseRecyclerAdapter.startListening();//将适配器设置为firebase回收器视图mRecyclerView.setAdapter(firebaseRecyclerAdapter);}//搜索数据private void firebaseSearch(String searchText) {//将SearchView中输入的字符串转换为小写字符串查询 = searchText.toLowerCase();查询 firebaseSearchQuery = mRef.orderByChild("search").startAt(query).endAt(query + "uf8ff");options = new FirebaseRecyclerOptions.Builder().setQuery(firebaseSearchQuery, Model.class).build();firebaseRecyclerAdapter = new FirebaseRecyclerAdapter(options) {@覆盖protected void onBindViewHolder(@NonNull ViewHolder holder, int position, @NonNull Model model) {holder.setDetails(getApplicationContext(),model.getTitle(),model.getDescription(),model.getImage());}@非空@覆盖public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {//膨胀布局row.xml查看 itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row, parent, false);ViewHolder viewHolder = new ViewHolder(itemView);//项目点击监听器viewHolder.setOnClickListener(new ViewHolder.ClickListener() {@覆盖public void onItemClick(View view, int position) {//在点击的位置从firebase获取数据String mTitle = getItem(position).getTitle();String mDesc = getItem(position).getDescription();String mImage = getItem(position).getImage();//将此数据传递给新活动Intent intent = new Intent(view.getContext(), PostDetailActivity.class);intent.putExtra("title", mTitle);//输入标题intent.putExtra("描述", mDesc);//输入描述intent.putExtra("image", mImage);//输入图片地址开始活动(意图);//开始活动}@覆盖public void onItemLongClick(View view, int position) {//Todo在这里实现你的长按功能}});返回 viewHolder;}};//设置布局为LinearLayoutmRecyclerView.setLayoutManager(mLayoutManager);firebaseRecyclerAdapter.startListening();//将适配器设置为firebase回收器视图mRecyclerView.setAdapter(firebaseRecyclerAdapter);}//将数据加载到回收器视图 onStart@覆盖受保护的无效 onStart() {super.onStart();如果(firebaseRecyclerAdapter !=null){firebaseRecyclerAdapter.startListening();}}@覆盖公共布尔 onCreateOptionsMenu(菜单菜单){//给菜单充气;如果它存在,这会将项目添加到操作栏getMenuInflater().inflate(R.menu.menu, menu);MenuItem item = menu.findItem(R.id.action_search);SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {@覆盖公共布尔 onQueryTextSubmit(字符串查询){火力搜索(查询);返回假;}@覆盖公共布尔 onQueryTextChange(String newText) {//输入时过滤火力搜索(新文本);返回假;}});返回 super.onCreateOptionsMenu(menu);}@覆盖公共布尔 onOptionsItemSelected(MenuItem item) {int id = item.getItemId();//处理其他操作栏项目点击这里如果(id == R.id.action_sort){//显示警报对话框以选择排序showSortDialog();返回真;}如果(id == R.id.action_add){//开始添加帖子活动开始活动(新意图(PostsListActivity.this,AddPostActivity.class));返回真;}返回 super.onOptionsItemSelected(item);}私有无效 showSortDialog() {//在对话框中显示的选项String[] sortOptions = {"最新", "最旧"};//创建警告对话框AlertDialog.Builder builder = new AlertDialog.Builder(this);builder.setTitle("Sort by")//设置标题.setIcon(R.drawable.ic_action_sort)//设置图标.setItems(sortOptions, new DialogInterface.OnClickListener() {@覆盖public void onClick(DialogInterface dialog, int which) {//'which' 参数包含所选项目的索引位置//0 表示最新",1 表示最旧"如果(其中 == 0){//按最新排序//编辑我们的共享偏好SharedPreferences.Editor 编辑器 = mSharedPref.edit();editor.putString("排序", "最新");//其中排序"是关键 &'最新'是价值editor.apply();//应用/保存我们共享首选项中的值重新创建();//重启activity生效} else if (which == 1) {{//按最旧排序//编辑我们的共享偏好SharedPreferences.Editor 编辑器 = mSharedPref.edit();editor.putString("排序", "最旧");//其中排序"是关键 &最古老"是价值editor.apply();//应用/保存我们共享首选项中的值重新创建();//重启activity生效}}}});builder.show();}}

解决方案

当我输入查询之间的某个单词时,它不起作用

发生这种情况是因为 Firebase 支持本地索引或在数据库属性中搜索文本字段.此外,下载整个节点以在客户端搜索字段根本不切实际.要启用 Firebase 实时数据库数据的全文搜索,我建议您使用第三方搜索服务,例如 AlgoliaElasticsearch.

这个 是一个示例,说明它如何与 Cloud Firestore 配合使用,但您也可以将其与 Firebase 实时数据库配合使用.

In my application, I have a real-time database in Firebase containing Title, Image, Description, Search(an extra field that is not displayed in the app but used contains the text of title with small case letters to make search case insensitive). Currently when I type query same to same either in small case or capital or with mixture of both it searches perfect, but when I type some word that is in between the query it doesn't work For example if the query is "This is long title" when I type "long" it shows nothing. I'm stuck help he solve this.

I have used firebase ui library:

implementation 'com.firebaseui:firebase-ui-database:4.2.0'

Realtime Database Screenshot:

Here is my activity code:

package com.blogspot.atifsoftwares.firebaseproject;

import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.SearchView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;

import java.io.ByteArrayOutputStream;

public class PostsListActivity extends AppCompatActivity {

    LinearLayoutManager mLayoutManager; //for sorting
    SharedPreferences mSharedPref; //for saving sort settings
    RecyclerView mRecyclerView;
    FirebaseDatabase mFirebaseDatabase;
    DatabaseReference mRef;

    FirebaseRecyclerAdapter<Model, ViewHolder> firebaseRecyclerAdapter;
    FirebaseRecyclerOptions<Model> options;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_posts_list);

        //Actionbar
        ActionBar actionBar = getSupportActionBar();
        //set title
        mSharedPref = getSharedPreferences("SortSettings", MODE_PRIVATE);
        String mSorting = mSharedPref.getString("Sort", "newest"); //where if no settingsis selected newest will be default

        if (mSorting.equals("newest")) {
            mLayoutManager = new LinearLayoutManager(this);
            //this will load the items from bottom means newest first
            mLayoutManager.setReverseLayout(true);
            mLayoutManager.setStackFromEnd(true);
        } else if (mSorting.equals("oldest")) {
            mLayoutManager = new LinearLayoutManager(this);
            //this will load the items from bottom means oldest first
            mLayoutManager.setReverseLayout(false);
            mLayoutManager.setStackFromEnd(false);
        }

        //RecyclerView
        mRecyclerView = findViewById(R.id.recyclerView);
        mRecyclerView.setHasFixedSize(true);

        //send Query to FirebaseDatabase
        mFirebaseDatabase = FirebaseDatabase.getInstance();
        mRef = mFirebaseDatabase.getReference("Data");

        showData();
    }

    //show data
    private void showData(){
        options = new FirebaseRecyclerOptions.Builder<Model>().setQuery(mRef, Model.class).build();

        firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Model, ViewHolder>(options) {
            @Override
            protected void onBindViewHolder(@NonNull ViewHolder holder, int position, @NonNull Model model) {
                holder.setDetails(getApplicationContext(), model.getTitle(), model.getDescription(), model.getImage());
            }

            @NonNull
            @Override
            public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                //Inflating layout row.xml
                View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row, parent, false);

                ViewHolder viewHolder = new ViewHolder(itemView);
                //item click listener
                viewHolder.setOnClickListener(new ViewHolder.ClickListener() {
                    @Override
                    public void onItemClick(View view, int position) {
                        //get data from firebase at the position clicked
                        String mTitle = getItem(position).getTitle();
                        String mDesc = getItem(position).getDescription();
                        String mImage = getItem(position).getImage();

                        //pass this data to new activity
                        Intent intent = new Intent(view.getContext(), PostDetailActivity.class);
                        intent.putExtra("title", mTitle); // put title
                        intent.putExtra("description", mDesc); //put description
                        intent.putExtra("image", mImage); //put image url
                        startActivity(intent); //start activity
                    }

                    @Override
                    public void onItemLongClick(View view, int position) {
                        //Todo implement you on long click functionality here
                    }
                });

                return viewHolder;
            }
        };

        //set layout as LinearLayout
        mRecyclerView.setLayoutManager(mLayoutManager);
        firebaseRecyclerAdapter.startListening();
        //set adapter to firebase recycler view
        mRecyclerView.setAdapter(firebaseRecyclerAdapter);
    }

    //search data
    private void firebaseSearch(String searchText) {

        //convert string entered in SearchView to lowercase
        String query = searchText.toLowerCase();

        Query firebaseSearchQuery = mRef.orderByChild("search").startAt(query).endAt(query + "uf8ff");


        options = new FirebaseRecyclerOptions.Builder<Model>().setQuery(firebaseSearchQuery, Model.class).build();

        firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Model, ViewHolder>(options) {
            @Override
            protected void onBindViewHolder(@NonNull ViewHolder holder, int position, @NonNull Model model) {
                holder.setDetails(getApplicationContext(), model.getTitle(), model.getDescription(), model.getImage());
            }

            @NonNull
            @Override
            public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                //Inflating layout row.xml
                View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row, parent, false);

                ViewHolder viewHolder = new ViewHolder(itemView);
                //item click listener
                viewHolder.setOnClickListener(new ViewHolder.ClickListener() {
                    @Override
                    public void onItemClick(View view, int position) {
                        //get data from firebase at the position clicked
                        String mTitle = getItem(position).getTitle();
                        String mDesc = getItem(position).getDescription();
                        String mImage = getItem(position).getImage();

                        //pass this data to new activity
                        Intent intent = new Intent(view.getContext(), PostDetailActivity.class);
                        intent.putExtra("title", mTitle); // put title
                        intent.putExtra("description", mDesc); //put description
                        intent.putExtra("image", mImage); //put image url
                        startActivity(intent); //start activity
                    }

                    @Override
                    public void onItemLongClick(View view, int position) {
                        //Todo implement you on long click functionality here
                    }
                });

                return viewHolder;
            }
        };

        //set layout as LinearLayout
        mRecyclerView.setLayoutManager(mLayoutManager);
        firebaseRecyclerAdapter.startListening();
        //set adapter to firebase recycler view
        mRecyclerView.setAdapter(firebaseRecyclerAdapter);

    }


    //load data into recycler view onStart
    @Override
    protected void onStart() {
        super.onStart();
        if (firebaseRecyclerAdapter !=null){
            firebaseRecyclerAdapter.startListening();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        //inflate the menu; this adds items to the action bar if it present
        getMenuInflater().inflate(R.menu.menu, menu);
        MenuItem item = menu.findItem(R.id.action_search);
        SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                firebaseSearch(query);
                return false;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                //Filter as you type
                firebaseSearch(newText);
                return false;
            }
        });
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        //handle other action bar item clicks here
        if (id == R.id.action_sort) {
            //display alert dialog to choose sorting
            showSortDialog();
            return true;
        }
        if (id == R.id.action_add) {
            //start Add Post Activity
            startActivity(new Intent(PostsListActivity.this, AddPostActivity.class));
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    private void showSortDialog() {
        //options to display in dialog
        String[] sortOptions = {" Newest", " Oldest"};
        //create alert dialog
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Sort by") //set title
                .setIcon(R.drawable.ic_action_sort) //set icon
                .setItems(sortOptions, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        // The 'which' argument contains the index position of the selected item
                        // 0 means "Newest" and 1 means "oldest"
                        if (which == 0) {
                            //sort by newest
                            //Edit our shared preferences
                            SharedPreferences.Editor editor = mSharedPref.edit();
                            editor.putString("Sort", "newest"); //where 'Sort' is key & 'newest' is value
                            editor.apply(); // apply/save the value in our shared preferences
                            recreate(); //restart activity to take effect
                        } else if (which == 1) {
                            {
                                //sort by oldest
                                //Edit our shared preferences
                                SharedPreferences.Editor editor = mSharedPref.edit();
                                editor.putString("Sort", "oldest"); //where 'Sort' is key & 'oldest' is value
                                editor.apply(); // apply/save the value in our shared preferences
                                recreate(); //restart activity to take effect
                            }
                        }
                    }
                });
        builder.show();
    }

}

解决方案

when I type some word that is in between the query it doesn't work

This is happening because Firebase does not support native indexing or search for text fields in database properties. Additionally, downloading an entire node to search for fields client-side isn't practical at all. To enable full text search of your Firebase realtime database data, I recommend you to use a third-party search service like Algolia or Elasticsearch.

This is an example on how it works with Cloud Firestore but in the same way you can use it with Firebase realtime database.

这篇关于Firebase 实时数据库在查询之间按单词搜索?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆