I have worked for search about how to search in firebase by vaule and I couldn't have a fully answer so I am asking now ...
I have used this method and I couldn't get the correct result:
I need to search by "Username".
Here's my database:
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
mQuery = mDatabase.orderByChild("Username");
return false;
}
});
And also I have used:
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
mQuery = mDatabase.orderByChild("Username").equalTo(newText)
return false;
}
});
but I couldn't so can anyone give me fully correct answer please
Thanks AtaerCaner for helping me and also thanks for trying to help me as much as you can, but I still haven't got any result from the Search View so I will give the method that is in my class:
mDatabase.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(final DataSnapshot dataSnapshot, String s) {
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
String A = (String) dataSnapshot.child(Post_Key).child("Username").getValue();
mQuery = mDatabase.orderByChild(A).equalTo(query);
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
String A = (String) dataSnapshot.child(Post_Key).child("Username").getValue();
mQuery = mDatabase.orderByChild(A).equalTo(newText);
return false;
}
});
}
So Please check the method if its correct or not ..
Let's think i'm searching Mike. First, bring all users by username with mDatabase.child("Users").orderByChild("Username"). But i want the Mike's datas, so i add .equalTo("Mike"). This returns a query as i say then set an .addListenerForSingleValueEvent to get datas of Mike. The information i want will come as iterable object with one item in this callback. Then cast it to your User modal.
mDatabase.child("Users").orderByChild("Username").equalTo("Mike").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
User user = dataSnapshot.getChildren().iterator().next().getValue(User.class);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
As far as i see in your code you get the query with mQuery = mDatabase.orderByChild(A).equalTo(newText) but you don't do anything with it.
Maybe this guy can help you
https://www.youtube.com/watch?v=3WTQZV5-roY
Related
when i fetch data from firebase to listview with a itemclicklistener and its working fine,
But when i add a searchview to the listview, Searchview will fetch the itementer image description here but the itemclicklistener showing a wrong result (its showing its position), Please help.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btMenu = findViewById(R.id.btMenu);
sr_txt = findViewById(R.id.sr_txt);
listView = findViewById(R.id.listView);
databaseReference = FirebaseDatabase.getInstance().getReference("dreamapp");
dream1 = new Dream();
title_list = new ArrayList<>();
answer_list = new ArrayList<>();
arrayAdapter = new ArrayAdapter<>(this,R.layout.item,R.id.item,title_list);
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot d:snapshot.getChildren())
{
dream1 = d.getValue(Dream.class);
title_list.add(dream1.getTitle());
answer_list.add(dream1.getAnswer());
}
listView.setAdapter(arrayAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int i,long id) {
Intent intent = new Intent(MainActivity.this, answer.class);
String p=answer_list.get(i);
intent.putExtra("answer",p);
startActivity(intent);
}
});
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
sr_txt.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
MainActivity.this.arrayAdapter.getFilter().filter(query);
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
MainActivity.this.arrayAdapter.getFilter().filter(newText);
return false;
}
});
}
And i have passed the answerlist values from firebase to another intent which is given below , where the result is fetching as position number from database which i need as itemsposition.
package com.example.dreamapp;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class answer extends AppCompatActivity {
TextView textView1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_answer);
textView1 = findViewById(R.id.answertext);
String answertxt = getIntent().getStringExtra("answer");
textView1.setText(answertxt);
}
}
Hi i have found the solution for this, When i added one more arrayadapter and listview , then i used it it in the searchview then it worked, it get the results if i search the exact words in it,
sr_txt.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
MainActivity.this.arrayAdapter.getFilter().filter(query);
MainActivity.this.arrayAdapter2.getFilter().filter(query);
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
MainActivity.this.arrayAdapter.getFilter().filter(newText);
MainActivity.this.arrayAdapter2.getFilter().filter(newText);
return false;
}
});
And SearchView
sr_txt.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
MainActivity.this.arrayAdapter.getFilter().filter(query);
MainActivity.this.arrayAdapter2.getFilter().filter(query);
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
MainActivity.this.arrayAdapter.getFilter().filter(newText);
MainActivity.this.arrayAdapter2.getFilter().filter(newText);
return false;
}
});
But still i face an issue with searchView, When i search it searches the entire characters from the array, i need a solution if i could search only five characters from it , it will work fine.
I have an android app which contains a search with firebase option and search with the api I'm using, the api takes a matter of seconds to print the data on the screen, while firebase takes minutes to print data and is slow to query the database
Here's my code:
public void firebaseSearch(String name) {
mFirebaseSearchList.clear();
mSearchLoading.setVisibility(View.VISIBLE);
mFirebaseSearchAdapter.setData(new ArrayList<_Release>());
mDatabase.child("releases")
.child(mRegion)
.child("data").orderByChild("game/search_name").startAt(name.toLowerCase())
.endAt(name.toLowerCase()+"\uf8ff")
.limitToFirst(10)
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
mSearchLoading.setVisibility(View.GONE);
if (dataSnapshot.hasChildren()) {
for (DataSnapshot data : dataSnapshot.getChildren()) {
_Release release = data.getValue(_Release.class);
if (release != null) {
mFirebaseSearchList.add(release);
mFirebaseSearchAdapter.notifyDataSetChanged();
}
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
mSearchLoading.setVisibility(View.GONE);
}
});
}
Listener is set to onTextChange
mGameSearchView.setOnQueryTextListener(new MaterialSearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
mGameSearchView.showSearch();
mGameSearchView.requestFocus();
if (currentSearchId == 2) {
apiSearch(query);
}
return true;
}
#Override
public boolean onQueryTextChange(String newText) {
if (currentSearchId == 1) {
firebaseSearch(newText);
}
return true;
}
});
Hi I am using Firebase Database with search query. I am also using offline method to store data from firebase offline. But after implementing searchview when I am opening the page it is showing blank. Data is coming after clicking the search icon. How to solve this? My application is on the playstore. It is the Link of the Application
And Here is my search query Code
private void firebaseUserSearch(String searchText) {
Query firebaseSearchQuery = mUserDatabase.orderByChild("Title").startAt(searchText).endAt(searchText + "\uf8ff");
FirebaseRecyclerAdapter<Blog,BlogViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Blog, BlogViewHolder>(
Blog.class,
R.layout.bank_row,
BlogViewHolder.class,
firebaseSearchQuery
) {
#Override
protected void populateViewHolder(BlogViewHolder viewHolder, final Blog model, int position) {
final String fav_key=getRef(position).getKey();
viewHolder.setDetails(getApplicationContext(), model.getTitle(), model.getDescription(), model.getExample());
viewHolder.setFavourite(fav_key);
viewHolder.favourite.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mfavourite=true;
databasefavourite.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(mfavourite){
if (dataSnapshot.child(fav_key).hasChild("Title")){
databasefavourite.child(fav_key).child("Title").removeValue();
mfavourite = false;
}else {
databasefavourite.child(fav_key).child("Title").setValue(model.getTitle());
mfavourite = false;
}
if (dataSnapshot.child(fav_key).hasChild("Description")){
databasefavourite.child(fav_key).child("Description").removeValue();
mfavourite = false;
}else {
databasefavourite.child(fav_key).child("Description").setValue(model.getDescription());
mfavourite = false;
}
if (dataSnapshot.child(fav_key).hasChild("Example")){
databasefavourite.child(fav_key).child("Example").removeValue();
mfavourite = false;
}else {
databasefavourite.child(fav_key).child("Example").setValue(model.getExample());
mfavourite = false;
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
});
}
};
mResultList.setAdapter(firebaseRecyclerAdapter);
}
It is my code for onStart()
#Override
protected void onStart() {
super.onStart();
FirebaseRecyclerAdapter<Blog,Idioms.BlogViewHolder>firebaseRecyclerAdapter=new FirebaseRecyclerAdapter<Blog, Idioms.BlogViewHolder>
(Blog.class,R.layout.bank_row,Idioms.BlogViewHolder.class,mUserDatabase) {
#Override
protected void populateViewHolder(Idioms.BlogViewHolder viewHolder, final Blog model, int position) {
final String fav_key=getRef(position).getKey();
viewHolder.setDetails(getApplicationContext(), model.getTitle(), model.getDescription(), model.getExample());
viewHolder.setFavourite(fav_key);
viewHolder.favourite.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mfavourite=true;
databasefavourite.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(mfavourite){
if (dataSnapshot.child(fav_key).hasChild("Title")){
databasefavourite.child(fav_key).child("Title").removeValue();
mfavourite = false;
}else {
databasefavourite.child(fav_key).child("Title").setValue(model.getTitle());
mfavourite = false;
}
if (dataSnapshot.child(fav_key).hasChild("Description")){
databasefavourite.child(fav_key).child("Description").removeValue();
mfavourite = false;
}else {
databasefavourite.child(fav_key).child("Description").setValue(model.getDescription());
mfavourite = false;
}
if (dataSnapshot.child(fav_key).hasChild("Example")){
databasefavourite.child(fav_key).child("Example").removeValue();
mfavourite = false;
}else {
databasefavourite.child(fav_key).child("Example").setValue(model.getExample());
mfavourite = false;
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
});
}
};
mResultList.setAdapter(firebaseRecyclerAdapter);
}
And it is my search action code
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_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) {
firebaseUserSearch(query);
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
firebaseUserSearch(newText);
return false;
}
});
return super.onCreateOptionsMenu(menu);
}
I'm doing a realtime tracking application from a tutorial online, Here i'm setting the presence system using firebase. But it's crashing with:
/java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.Boolean.booleanValue()' on a null object reference
I don't understand what's wrong the guy who coded this has it working perfectly.
The exception is happening at this line :if(dataSnapshot.getValue(Boolean.class)){
When i log this on screen the datasnapshot object has a key but no value
HELP!
ListOnline Class
//firebase
DatabaseReference onlineRef,currentUserRef,counterRef;
FirebaseRecyclerAdapter<User,ListOnlineViewHolder> adapter;
//View
RecyclerView listOnline;
RecyclerView.LayoutManager layoutManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_online);
//setting the recyclerview
listOnline = (RecyclerView)findViewById(R.id.listOnlineRecyclerview);
listOnline.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
listOnline.setLayoutManager(layoutManager);
//set toolbar and menu / join,logout
Toolbar toolbar = (Toolbar)findViewById(R.id.toolbarID);
toolbar.setTitle("Presence System");
setSupportActionBar(toolbar);
//firebase
onlineRef = FirebaseDatabase.getInstance().getReference().child("info/connected");
counterRef = FirebaseDatabase.getInstance().getReference("lastOnline"); //create new child name lastOnline
currentUserRef = FirebaseDatabase.getInstance().getReference().child(FirebaseAuth.getInstance().getCurrentUser().getUid());
setupSystem();
//after setup we load all users and display in recyclerview
//this is online list
updateList();
}
private void updateList() {
adapter = new FirebaseRecyclerAdapter<User, ListOnlineViewHolder>(
User.class,R.layout.user_layout,ListOnlineViewHolder.class,counterRef
) {
#Override
protected void populateViewHolder(ListOnlineViewHolder viewHolder, User model, int position) {
viewHolder.emailTextView.setText(model.getEmail());
}
};
adapter.notifyDataSetChanged();
listOnline.setAdapter(adapter);
}
private void setupSystem() {
onlineRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.getValue(Boolean.class)){
currentUserRef.onDisconnect().removeValue();
//set online user in list
counterRef.child(FirebaseAuth.getInstance().getCurrentUser().getUid())
.setValue(FirebaseAuth.getInstance().getCurrentUser().getEmail(),"Online");
adapter.notifyDataSetChanged();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
counterRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot postSnapshot:dataSnapshot.getChildren()){
User user = postSnapshot.getValue(User.class);
Log.d("LOG",""+user.getEmail()+"is "+user.getStatus());
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.main_menu,menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.action_join:
counterRef.child(FirebaseAuth.getInstance().getCurrentUser().getUid())
.setValue(FirebaseAuth.getInstance().getCurrentUser().getEmail(),"Online");
break;
case R.id.action_logout:
currentUserRef.removeValue();
}
return super.onOptionsItemSelected(item);
}
}
User Class
public class User {
private String email,status;
public User(String email, String status) {
this.email = email;
this.status = status;
}
public User() {
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}}
MainActivity
public class MainActivity extends AppCompatActivity {
Button signInButton;
private final static int LOGIN_PERMISSION = 1000;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
signInButton = (Button) findViewById(R.id.signInButton);
signInButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivityForResult(AuthUI.getInstance().createSignInIntentBuilder().setAllowNewEmailAccounts(true).build(),LOGIN_PERMISSION);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == LOGIN_PERMISSION){
startNewActivity(resultCode,data);
}
}
private void startNewActivity(int resultcode, Intent data) {
if(resultcode == RESULT_OK){
Intent intent = new Intent(MainActivity.this,ListOnline.class);
startActivity(intent);
finish();
}
else{
Toast.makeText(this,"login failed!!",Toast.LENGTH_SHORT).show();
}
}}
In your setupSystem() method, you are attaching a listener to onlineRef (the info/connected node) and then marshalling the returned value to a Boolean value.
However, DataSnapshot#getValue() will return null if there is no data at the specified location in the database. If this happens, the dataSnapshot.getValue(Boolean.class) call will create a Boolean variable with the value of null, which then cannot be checked for a true value in your current if statement (see Check if null Boolean is true results in exception).
You could check that getValue() does not return null first by adding a null-check to your if statement:
if(dataSnapshot.getValue() != null && dataSnapshot.getValue(Boolean.class)){
// ...
}
Or check that the location exists using DataSnapshot#exists():
if(dataSnapshot.exists() && dataSnapshot.getValue(Boolean.class)){
// ...
}
However, if you're trying to detect connection state, did you mean to attach the listener to the .info/connected node instead? As from the documentation:
For many presence-related features, it is useful for your app to know
when it is online or offline. Firebase Realtime Database provides a
special location at /.info/connected which is updated every time the
Firebase Realtime Database client's connection state changes. Here is
an example:
DatabaseReference connectedRef = FirebaseDatabase.getInstance().getReference(".info/connected");
connectedRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
boolean connected = snapshot.getValue(Boolean.class);
if (connected) {
System.out.println("connected");
} else {
System.out.println("not connected");
}
}
#Override
public void onCancelled(DatabaseError error) {
System.err.println("Listener was cancelled");
}
});
its null since it does not exist in the database..
onlineRef = FirebaseDatabase.getInstance().getReference().child("info/connected");
you are querying on the above location. So dataSnapshot is a snapshot of the above..
if(dataSnapshot.getValue(Boolean.class)){
This does not exist in the database.. Thus you get that error
It seems that you do not have a value in database. This will handle the error
if(dataSnapshot.getValue(Boolean.class) != null && dataSnapshot.getValue(Boolean.class)){
I can able to retrieve data from Firebase to App through RecyclerView. But when I am trying to add Search view its not working.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_search, menu);
final SearchView searchView =(SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.menusearch));
SearchManager searchManager =(SearchManager) getSystemService(SEARCH_SERVICE); searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName());
//searchView.setSubmitButtonEnabled(true);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
//SearchText.setText(newText);
Query Q = mDatabase.child("Recipees").orderByChild("cusine").startAt(newText).endAt("");
FirebaseRecyclerAdapter<ImageRetrieve, BlogViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<ImageRetrieve, BlogViewHolder>(
ImageRetrieve.class,
R.layout.recipe_row,
BlogViewHolder.class,
Q
) {
#Override
protected void populateViewHolder(BlogViewHolder viewHolder, ImageRetrieve model, int position) {
viewHolder.setCusine(model.getCusine());
viewHolder.setCatagory(model.getCatagory());
viewHolder.setRecipe(model.getRecipe());
viewHolder.setUrl(getApplicationContext(), model.getUrl());
}
};
mRecipeList.setAdapter(firebaseRecyclerAdapter);
return false;
}
});
return true;
}
Try this it may help :
Query Q = mDatabase.child("Recipees").orderByChild("cusine").startAt(newText).endAt(newText+"\uf8ff");
So that mean query have wrong.
Try This:-->
mDatabase.child("Recipees").orderByChild("cusine").equalTo(newText);
Try the code below, it might be helpful:
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String text) {
return false;
}
#Override
public boolean onQueryTextChange(String text) {
// if searchView is not empty
if(!text.isEmpty()){
// call seearch method if user starts typing
search(text);
}
//else
else{
// set TextField empty
search("");
}
return true;
}
});
// method to perform search
private void search(String newText)
{
ArrayList<> searchList = new ArrayList<>();
// creates a query to initiate the search
Query Q = mDatabase.child("Recipees")
.orderByChild("cusine").startAt(newText).endAt(newText + "\uf8ff");
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.hasChildren()){
//clears the arrayList
searchList.clear();
for(DataSnapshot snapshot : dataSnapshot.getChildren()){
final ImageRetrieve imageRetrieve =
snapshot.getValue(ImageRetrieve.class);
//adds the rooms searched to the arrayList
searchList.add(imageRetrieve);
}
//NB: recyclerView is the view object in your activity that populates data
FirebaseRecyclerAdapter firebaseRecyclerAdapter =
new FirebaseRecyclerAdapter(yourActivity.this,searchList);
recyclerView.setAdapter(firebaseRecyclerAdapter);
firebaseRecyclerAdapter.notifyDataSetChanged();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
// display message if error occurs
}
});
}