在我的应用程序中,我在 Firebase 中有一个实时数据库,其中包含标题、图像、描述、搜索(应用程序中未显示但使用的额外字段包含带有小写字母的标题文本以进行搜索不敏感)。目前,当我在小写字母或大写字母或两者混合时键入相同的查询时,它搜索完美,但是当我键入查询之间的某个单词时,它不起作用例如,如果查询是“This is long title”,当我输入“long”时,它什么也没有显示。我无法帮助他解决这个问题。
我用过firebase ui图书馆:
implementation 'com.firebaseui:firebase-ui-database:4.2.0'
这是我的 Activity 代码:
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
发生这种情况是因为 Firebase 不支持本地索引或在数据库属性中搜索文本字段。此外,下载整个节点以在客户端搜索字段根本不切实际。要启用 Firebase 实时数据库数据的全文搜索,我建议您使用第三方搜索服务,如 Algolia或 Elasticsearch .
This 是一个示例,说明它如何与 Cloud Firestore 一起使用,但您可以使用与 Firebase 实时数据库相同的方式使用它。
关于java - Firebase 实时数据库在查询之间按单词搜索?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52789675/
我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.
我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr
在Cooper的书BeginningRuby中,第166页有一个我无法重现的示例。classSongincludeComparableattr_accessor:lengthdef(other)@lengthother.lengthenddefinitialize(song_name,length)@song_name=song_name@length=lengthendenda=Song.new('Rockaroundtheclock',143)b=Song.new('BohemianRhapsody',544)c=Song.new('MinuteWaltz',60)a.betwee
我正在检查一个Rails项目。在ERubyHTML模板页面上,我看到了这样几行:我不明白为什么不这样写:在这种情况下,||=和ifnil?有什么区别? 最佳答案 在这种特殊情况下没有区别,但可能是出于习惯。每当我看到nil?被使用时,它几乎总是使用不当。在Ruby中,很少有东西在逻辑上是假的,只有文字false和nil是。这意味着像if(!x.nil?)这样的代码几乎总是更好地表示为if(x)除非期望x可能是文字false。我会将其切换为||=false,因为它具有相同的结果,但这在很大程度上取决于偏好。唯一的缺点是赋值会在每次运行
我使用Nokogiri(Rubygem)css搜索寻找某些在我的html里面。看起来Nokogiri的css搜索不喜欢正则表达式。我想切换到Nokogiri的xpath搜索,因为这似乎支持搜索字符串中的正则表达式。如何在xpath搜索中实现下面提到的(伪)css搜索?require'rubygems'require'nokogiri'value=Nokogiri::HTML.parse(ABBlaCD3"HTML_END#my_blockisgivenmy_bl="1"#my_eqcorrespondstothisregexmy_eq="\/[0-9]+\/"#FIXMEThefoll
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我