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