I am trying to read "specific" data from my firebase realtime database. I have seen examples of getting all data from a table and going through it to find the data record you want.
Below is how I save my data`
FirebaseDatabase database;
DatabaseReference foodList;
String categoryId="";
FirebaseRecyclerAdapter<Food,FoodViewHolder>adapter;
FirebaseRecyclerAdapter<Food,FoodViewHolder>searchAdapter;
List<String> suggestList=new ArrayList<>();
MaterialSearchBar materialSearchBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_food_list);
database=FirebaseDatabase.getInstance();
foodList=database.getReference("Foods");
recyclerView=findViewById(R.id.recycler_food);
recyclerView.setHasFixedSize(true);
layoutManager=new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
if(getIntent()!=null)
{
categoryId=getIntent().getStringExtra("CategoryId");
}
if(!categoryId.isEmpty() )
{
loadListFood(categoryId);
}
materialSearchBar=findViewById(R.id.searchBar);
materialSearchBar.setHint("Enter food name");
loadSuggestion();
materialSearchBar.setLastSuggestions(suggestList);
materialSearchBar.setCardViewElevation(10);
materialSearchBar.addTextChangeListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
List<String>suggest=new ArrayList<>();
for (String search:suggestList)
{
if(search.toLowerCase().contains(materialSearchBar.getText().toLowerCase()))
suggest.add(search);
}
materialSearchBar.setLastSuggestions(suggest);
}
#Override
public void afterTextChanged(Editable s) {
}
});
materialSearchBar.setOnSearchActionListener(new MaterialSearchBar.OnSearchActionListener() {
#Override
public void onSearchStateChanged(boolean enabled) {
if(!enabled)
{
recyclerView.setAdapter(adapter);
}
}
#Override
public void onSearchConfirmed(CharSequence text) {
startSearch(text);
}
#Override
public void onButtonClicked(int buttonCode) {
}
});
}
private void startSearch(CharSequence text) {
searchAdapter = new FirebaseRecyclerAdapter<Food, FoodViewHolder>(
Food.class,
R.layout.food_item,
FoodViewHolder.class,
foodList.orderByChild("Name").equalTo(text.toString())// compare Food Name//////
) {
#Override
protected void populateViewHolder(FoodViewHolder viewHolder, Food model, int position) {
viewHolder.food_name.setText(model.getName());
Picasso.with(getBaseContext()).load(model.getImage()).into(viewHolder.food_image);
final Food local=model;
viewHolder.setItemClickListner(new ItemClickListner() {
#Override
public void onClick(View view, int position, boolean isLongClick) {
Toast.makeText(FoodList.this,""+local.getName(),Toast.LENGTH_SHORT).show();//there is problem local.getName???????????
//Start new Acitvity
Intent foodDetail=new Intent(FoodList.this,FoodDetail.class);
foodDetail.putExtra("FoodId",searchAdapter.getRef(position).getKey());//send Food ID to new Acitivity
startActivity(foodDetail);
}
});
}
};
recyclerView.setAdapter(searchAdapter);
}
private void loadSuggestion() {
foodList.orderByChild("MenuId").equalTo(categoryId)
.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot postSnapshot:dataSnapshot.getChildren() )
{
Food item=postSnapshot.getValue(Food.class);
suggestList.add(item.getName());
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private void loadListFood(String categoryId) {
adapter=new FirebaseRecyclerAdapter<Food, FoodViewHolder>(Food.class,
R.layout.food_item,
FoodViewHolder.class,
foodList.orderByChild("menuId").equalTo(categoryId))
{
#Override
protected void populateViewHolder(FoodViewHolder viewHolder, Food model, int position) {
viewHolder.food_name.setText(model.getName());
Picasso.with(getBaseContext()).load(model.getImage()).into(viewHolder.food_image);
final Food local=model;
viewHolder.setItemClickListner(new ItemClickListner() {
#Override
public void onClick(View view, int position, boolean isLongClick) {
Toast.makeText(FoodList.this,""+local.getName(),Toast.LENGTH_SHORT).show();
Intent foodDetail=new Intent(FoodList.this,FoodDetail.class);
foodDetail.putExtra("FoodId",adapter.getRef(position).getKey());
startActivity(foodDetail);
}
});
}
};
recyclerView.setAdapter(adapter);
}
}
UPDATE
When I try to get the data from firebase to update the food list , i didn't found the database to change. Below is database that i want to update.
Related
It's an app that retrieves book data from firebase, I want to know how to retrieve specific data into a new activity. Like, retrieve specific book data on click RecyclerView. I am able to get the onclick position on the RecyclerView but I don't know how to use that with firebase
Here is my code:
public class SearchPage extends AppCompatActivity {
EditText searchbar;
RecyclerView recyclerView;
DatabaseReference reference;
ArrayList <String> BookNameList;
ArrayList <String> AuthorNameList;
ArrayList <String> PicList;
ArrayList <String> PublisherList;
ArrayList <String> Shelfnols;
ArrayList <String> Desc;
SearchAdapter searchAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search_page);
searchbar = (EditText) findViewById(R.id.searchbar);
reference = FirebaseDatabase.getInstance().getReference();
reference.keepSynced(true);
recyclerView = (RecyclerView) findViewById(R.id.rv);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));
BookNameList = new ArrayList <> ();
PublisherList = new ArrayList <> ();
AuthorNameList = new ArrayList <> ();
Shelfnols = new ArrayList <> ();
PicList = new ArrayList <> ();
Desc = new ArrayList <> ();
final ArrayList <String> uidlist = new ArrayList <String> ();
searchbar.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
if (!s.toString().isEmpty()) {
setAdapter(s.toString());
} else {
BookNameList.clear();
AuthorNameList.clear();
PicList.clear();
PublisherList.clear();
Shelfnols.clear();
Desc.clear();
uidlist.clear();
}
}
private void setAdapter(final String searchedString) {
reference.child("books").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
BookNameList.clear();
AuthorNameList.clear();
PicList.clear();
PublisherList.clear();
Shelfnols.clear();
Desc.clear();
uidlist.clear();
int counter = 0;
for (DataSnapshot snapshot: dataSnapshot.getChildren()) {
String uid = snapshot.getKey();
String desc = snapshot.child("Desc").getValue(String.class);
String bookname = snapshot.child("bookname").getValue(String.class);
String author = snapshot.child("author").getValue(String.class);
String image = snapshot.child("image").getValue(String.class);
String publisher = snapshot.child("Publisher").getValue(String.class);
String shelfno = snapshot.child("Shelf_no").getValue(String.class);
try {
if (bookname.toLowerCase().contains(searchedString.toLowerCase())) {
BookNameList.add(bookname);
AuthorNameList.add(author);
PublisherList.add(publisher);
Shelfnols.add(shelfno);
PicList.add(image);
Desc.add(desc);
counter++;
} else if (author.toLowerCase().contains(searchedString.toLowerCase())) {
BookNameList.add(bookname);
AuthorNameList.add(author);
PublisherList.add(publisher);
Shelfnols.add(shelfno);
PicList.add(image);
Desc.add(desc);
counter++;
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "not found", Toast.LENGTH_LONG).show();
}
if (counter == 15) {
break;
}
SearchAdapter searchAdapter = new SearchAdapter(SearchPage.this, BookNameList, AuthorNameList, PicList, PublisherList, Shelfnols);
recyclerView.setAdapter(searchAdapter);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
});
}
This is my adapter class
public class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.SearchViewHolder> {
public static final String id="key";
Context context;
ArrayList<String> BookNameList;
ArrayList<String> AuthorNameList;
ArrayList<String> PicList;
ArrayList<String> PublisherList;
ArrayList<String> Shelfnols;
LinearLayout booklayout;
class SearchViewHolder extends RecyclerView.ViewHolder{
ImageView bookimage;
TextView bookname, authorname,publisher,shelfno;
public SearchViewHolder(#NonNull View itemView) {
super(itemView);
bookimage = itemView.findViewById(R.id.Bookimg);
bookname = itemView.findViewById(R.id.BookName);
authorname = itemView.findViewById(R.id.AuthorName);
publisher = itemView.findViewById(R.id.Publications);
shelfno = itemView.findViewById(R.id.Shelfno);
booklayout=itemView.findViewById(R.id.LinLayout);
}
}
public SearchAdapter(Context context, ArrayList<String> bookNameList, ArrayList<String> authorNameList, ArrayList<String> picList,ArrayList<String> publisherList,ArrayList<String> shelfnols) {
this.context = context;
BookNameList = bookNameList;
AuthorNameList = authorNameList;
PicList = picList;
PublisherList=publisherList;
Shelfnols=shelfnols;
}
#NonNull
#Override
public SearchAdapter.SearchViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.activity_search_layout,parent,false);
return new SearchAdapter.SearchViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull SearchViewHolder holder, final int position) {
holder.bookname.setText(BookNameList.get(position));
holder.authorname.setText(AuthorNameList.get(position));
holder.publisher.setText(PublisherList.get(position));
holder.shelfno.setText(Shelfnols.get(position));
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String t=String.valueOf(position);
Toast.makeText(v.getContext(), "Item is clicked" + t, Toast.LENGTH_SHORT).show();
}
});
booklayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
this the new activity where i want the book details to be shown
public class Bookdetailslayout extends SearchPage {
DatabaseReference reference;
TextView bookname,author,publisher,desc,location;
ImageView image;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bookdetailslayout);
bookname = (TextView)findViewById(R.id.bkname);
author = (TextView) findViewById(R.id.aname);
publisher = (TextView) findViewById(R.id.pname);
desc = (TextView) findViewById(R.id.bkdescription);
location = (TextView) findViewById(R.id.bklocation);
String s = getIntent().getStringExtra("key");
DatabaseReference databaseReference=FirebaseDatabase.getInstance().getReference().child("books");
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
Bookdeets bookdeets=dataSnapshot.getValue(Bookdeets.class);
bookname.setText(bookdeets.getBookname());
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
Glide.with(context).asBitmap().load(PicList.get(position)).placeholder(R.mipmap.ic_launcher_round).into(holder.bookimage);
}
#Override
public int getItemCount() {
return BookNameList.size();
}
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(context,BookdetailsActivity.class);
i.putExtra("bookname",bookname);
context.startActivity(i);
}
});
above code start new activity for showing details on new activity at the same time pass unique key for retrieving data from firebase.
inside BookDetailsActivity
get key value by using
String name = getIntent().getStringExtra("bookname");
then do your stuff for getting data from firebase.
I am using com.github.mancj:MaterialSearchBar:+ dependency in my app to search data in my SQLite database. It does load suggestions based on the data i have in the database but when a user clicks on one of the suggestion and confirms it by clicking the search icon in the keyboard nothing gets displayed, the adapter is not being called to display the result. below is my search activity
recyclerView = findViewById(R.id.hyme_list);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
materialSearchBar = findViewById(R.id.searchBar);
database = new Database(this);
materialSearchBar.setHint("Search here");
materialSearchBar.setCardViewElevation(10);
loadSuggestList();
materialSearchBar.addTextChangeListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
List<String> sugest = new ArrayList<>();
for (String search: suggestList) {
if (search.toUpperCase().contains(materialSearchBar.getText().toUpperCase()))
sugest.add(search);
}
materialSearchBar.setLastSuggestions(sugest);
}
#Override
public void afterTextChanged(Editable editable) {
}
});
materialSearchBar.setOnSearchActionListener(new MaterialSearchBar.OnSearchActionListener() {
#Override
public void onSearchStateChanged(boolean enabled) {
if (!enabled){
searchAdapter = new SearchAdapter(getBaseContext(),database.getSongs());
recyclerView.setAdapter(searchAdapter);
}
}
#Override
public void onSearchConfirmed(CharSequence text) {
startSearch(text.toString());
}
#Override
public void onButtonClicked(int buttonCode) {
}
});
searchAdapter = new SearchAdapter(this,database.getSongs());
recyclerView.setAdapter(searchAdapter);
}
private void startSearch(String text) {
searchAdapter = new SearchAdapter(this,database.getSongByName(text));
recyclerView.setAdapter(searchAdapter);
}
private void loadSuggestList() {
suggestList = database.getTitle();
materialSearchBar.setLastSuggestions(suggestList);
}
I am trying to implement a search filter on complex object data in recyclerview when I type in the Edit text first-time it works properly, but whenever I try to delete characters by pressing back-space in order to modify our search- I am repeatedly failing in this regard.
I can only search once !!
etSearch = (EditText) findViewById(R.id.edittext);
etSearch.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
myAdapter.filter(s);
}
#Override
public void afterTextChanged(Editable s) {
}
});
now the filter code
public void filter(CharSequence sequence) {
ArrayList<user> temp = new ArrayList<>();
if (!TextUtils.isEmpty(sequence)) {
for (user s : arr) {
Log.d("users ",s.getName());
if (s.getName().toLowerCase().contains(sequence)) {
temp.add(s);
}
}
} else {
temp.addAll(arrcopy);
}
arr.clear();
arr.addAll(temp);
notifyDataSetChanged();
temp.clear();
}
Whats the issue, I cannot search more than once-any help is appreciated
Here is my Adapter class
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyHolder>
{
Context cxt;
ArrayList<user> arr;
ArrayList<user> arrcopy;
DatabaseReference dref;
MyAdapter myAdapter;
public MyAdapter(Context context, ArrayList<user> arrayList)
{
cxt = context;
arr = arrayList;
arrcopy=new ArrayList<>(arr);
Log.d("Very start arr",arr.toString());
notifyDataSetChanged();
dref = FirebaseDatabase.getInstance().getReference("users");
}
#NonNull
#Override
public MyHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(cxt).inflate(R.layout.item_chatroom,viewGroup,false);
myAdapter = new MyAdapter(cxt, arr);
Log.d("Inside MyHolder arr",arr.toString());
return new MyHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final MyHolder myHolder,final int i) {
final String name = arr.get(i).getUsername();
String pic=arr.get(i).getPic();
final String mail=arr.get(i).getEmail();
myHolder.name.setText(name);
Glide.with(myHolder.profile.getContext())
.load(pic)
.into(myHolder.profile);
myHolder.name.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(cxt,MainActivity.class);
intent.putExtra("Id",arr.get(i).getId());
intent.putExtra("Name",arr.get(i).getUsername());
cxt.startActivity(intent);
}
});
myHolder.info.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final SweetAlertDialog pDialog = new SweetAlertDialog(cxt, SweetAlertDialog.SUCCESS_TYPE);
pDialog.setTitleText("User Information e-mail ID");
pDialog.setContentText("Name: "+name+"\n\n E-mail: "+mail);
pDialog.setConfirmText("Ok");
pDialog.show();
}
});
}
#Override
public int getItemCount() {
return arr.size();
}
class MyHolder extends RecyclerView.ViewHolder
{
TextView name;
ImageView profile,info;
public MyHolder(#NonNull View itemView) {
super(itemView);
name = itemView.findViewById(R.id.txv);
profile=itemView.findViewById(R.id.profile);
info=itemView.findViewById(R.id.profileinfo);
}
}
public void filter(CharSequence sequence) {
ArrayList<user> temp = new ArrayList<>();
if (!TextUtils.isEmpty(sequence)) {
for (user s : arr) {
if (s.getName().toLowerCase().contains(sequence)) {
temp.add(s);
}
}
} else {
temp.addAll(arrcopy);
}
arr.clear();
arr.addAll(temp);
notifyDataSetChanged();
temp.clear();
}
}
I assume the arrcopy is the copy of arr like:
ArrayList<User> arrcopy = new ArrayList<>(arr);
If you modify arr, it also change the content of arrcopy. And when no result matches, the arr is empty, so is the arrcopy.
else {
temp.addAll(arrcopy);
}
arr.clear();
arr.addAll(temp);
Now temp is empty, the arr data you set for adapter is empty, so issues happens.
Please try:
In MyAdapter:
Context cxt;
ArrayList<user> arr;
public MyAdapter(Context context) {
cxt = context;
dref = FirebaseDatabase.getInstance().getReference("users");
}
public void setData(ArrayList<User> arrayList) {
arr = arrayList;
notifyDataSetChanged();
}
Also put the filter() in your activity/fragment:
protected void onCreate(final Bundle savedInstanceState) {
etSearch = (EditText) findViewById(R.id.edittext);
etSearch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
etSearch.requestFocus();
}
});
etSearch.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
filter(etSearch.getText().toString());
}
#Override
public void afterTextChanged(Editable s) {
}
});
etSearch.clearFocus();
mAdapter = new MyAdapter(this);
mAdapter.setData(arrayList);
mRecyclerView.setAdapter(mAdapter);
...
}
public void filter(String input) {
if (!TextUtils.isEmpty(input)) {
ArrayList<User> temp = new ArrayList<>();
for (user s : arr) {
if (s.getName().toLowerCase().contains(input)) {
temp.add(s);
}
}
mAdapter.setData(temp);
} else {
mAdapter.setData(arr);
}
mAdapter.notifyDataSetChanged();
}
Implement Filterable in your MyAdapter
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyHolder>
implements Filterable {
// change MyObject to user class
//replace myObjects with arr and reservedList with arrcopy
Context cxt;
ArrayList<MyObject> myObjects;
ArrayList<MyObject> reservedList;
DatabaseReference dref;
public MyAdapter(Context context, ArrayList<MyObject> arrayList){
cxt = context;
myObjects = arrayList;
reservedList = arrayList
Log.d("Very start arr",myObjects.toString());
// notifyDataSetChanged();
dref = FirebaseDatabase.getInstance().getReference("users");
}
//...
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
String charString = charSequence.toString().toLowerCase();
if (!charString.isEmpty()) {
List<MyObject> filteredList = new ArrayList<>();
for (MyObject row : reservedList) {
if (row.getName().toLowerCase().contains(charString)){
filteredList.add(row);
}
}
myObjects = filteredList;
} else {
myObjects = reservedList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = myObjects;
return filterResults;
}
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
myObjects = (ArrayList<MyObject>) filterResults.values;
notifyDataSetChanged();
}
};
}
and from your activity
etSearch = (EditText) findViewById(R.id.edittext);
etSearch.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
myAdapter.getFilter().filter(s);
}
#Override
public void afterTextChanged(Editable s) {
}
});
I am building the chat app and I am having the issue with populating the view using FirebaseRecyclerAdapter. I not able to figure out what error causing to it.
My Activity class:
public class HomeActivity extends AppCompatActivity implements AIListener, View.OnClickListener {
RecyclerView recyclerView;
EditText editText;
RelativeLayout addBtn;
DatabaseReference ref;
Boolean flagFab = true;
FirebaseRecyclerAdapter<ChatMessageModel,chat_viewholder> adapter;
AIDataService aiDataService;
AIRequest aiRequest;
private AIService aiService;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.RECORD_AUDIO},1);
recyclerView = findViewById(R.id.recycleview);
editText = findViewById(R.id.editText);
addBtn = findViewById(R.id.addBtn);
recyclerView.setHasFixedSize(true);
final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(linearLayoutManager);
ref = FirebaseDatabase.getInstance().getReference().child("chat");
ref.keepSynced(true);
final AIConfiguration configuration = new AIConfiguration("c0a5bbcb6d2b4c17a9b8ae15d7e4f43f",
AIConfiguration.SupportedLanguages.English,
AIConfiguration.RecognitionEngine.System);
aiService = AIService.getService(this,configuration);
aiService.setListener(this);
aiDataService = new AIDataService(configuration);
aiRequest = new AIRequest();
addBtn.setOnClickListener(this);
editText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
ImageView fab_img = findViewById(R.id.fab_img);
Bitmap img = BitmapFactory.decodeResource(getResources(),R.drawable.ic_send_white_24dp);
Bitmap img1 = BitmapFactory.decodeResource(getResources(),R.drawable.ic_mic_white_24dp);
if (s.toString().trim().length()!=0 && flagFab){
ImageViewAnimatedChange(HomeActivity.this,fab_img,img);
flagFab=false;
}
else if (s.toString().trim().length()==0){
ImageViewAnimatedChange(HomeActivity.this,fab_img,img1);
flagFab=true;
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
FirebaseRecyclerOptions options =
new FirebaseRecyclerOptions.Builder<ChatMessageModel>()
.setQuery(ref, ChatMessageModel.class)
.build();
adapter = new FirebaseRecyclerAdapter<ChatMessageModel, chat_viewholder>(options){
#NonNull
#Override
public chat_viewholder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.msg_list,parent,false);
return new chat_viewholder(view);
}
#Override
protected void onBindViewHolder(#NonNull chat_viewholder viewHolder, int position, #NonNull ChatMessageModel model) {
if(model.getMsgUser().equals("user")){
viewHolder.rightText.setText(model.getMsgText());
viewHolder.rightText.setVisibility(View.VISIBLE);
viewHolder.leftText.setVisibility(View.GONE);
}else {
viewHolder.leftText.setText(model.getMsgText());
viewHolder.leftText.setVisibility(View.VISIBLE);
viewHolder.rightText.setVisibility(View.GONE);
}
}
};
adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
#Override
public void onItemRangeInserted(int positionStart, int itemCount) {
super.onItemRangeInserted(positionStart, itemCount);
int msgcount = adapter.getItemCount();
int lastVisiblePosition = linearLayoutManager.findLastCompletelyVisibleItemPosition();
if(lastVisiblePosition == -1 || (positionStart >= (msgcount -1) && lastVisiblePosition == (positionStart - 1))){
recyclerView.scrollToPosition(positionStart);
}
}
});
recyclerView.setAdapter(adapter);
}
#Override
public void onStart() {
super.onStart();
adapter.startListening();
}
#Override
public void onStop() {
super.onStop();
if(adapter != null) {
adapter.stopListening();
}
}
public void ImageViewAnimatedChange(Context c, final ImageView v, final Bitmap new_image) {
final Animation anim_out = AnimationUtils.loadAnimation(c, R.anim.zoom_out);
final Animation anim_in = AnimationUtils.loadAnimation(c, R.anim.zoom_in);
anim_out.setAnimationListener(new Animation.AnimationListener()
{
#Override public void onAnimationStart(Animation animation) {}
#Override public void onAnimationRepeat(Animation animation) {}
#Override public void onAnimationEnd(Animation animation)
{
v.setImageBitmap(new_image);
anim_in.setAnimationListener(new Animation.AnimationListener() {
#Override public void onAnimationStart(Animation animation) {}
#Override public void onAnimationRepeat(Animation animation) {}
#Override public void onAnimationEnd(Animation animation) {}
});
v.startAnimation(anim_in);
}
});
v.startAnimation(anim_out);
}
#Override
public void onClick(View v) {
String message = editText.getText().toString().trim();
Log.d("message",message);
if(!message.equals("")){
final ChatMessageModel chatMessageModel = new ChatMessageModel(message,"user");
ref.child("chat").push().setValue(chatMessageModel);
aiRequest.setQuery(message);
new AsyncTask<AIRequest,Void,AIResponse>(){
#Override
protected AIResponse doInBackground(AIRequest... aiRequests) {
final AIRequest request = aiRequests[0];
try{
final AIResponse response = aiDataService.request(request);
return response;
} catch (AIServiceException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(AIResponse aiResponse) {
super.onPostExecute(aiResponse);
if(aiResponse!= null){
Result result = aiResponse.getResult();
String reply = result.getFulfillment().getSpeech();
ChatMessageModel chatMessageModel1 = new ChatMessageModel(reply,"bot");
ref.child("chat").push().setValue(chatMessageModel);
}
}
}.execute(aiRequest);
}else {
aiService.startListening();
}
editText.setText("");
}
#Override
public void onResult(AIResponse response) {
Result result = response.getResult();
String message = result.getResolvedQuery();
Log.d("AI response",result.getFulfillment().getSpeech());
ChatMessageModel chatMessageModel0 = new ChatMessageModel(message, "user");
ref.child("chat").push().setValue(chatMessageModel0);
String reply = result.getFulfillment().getSpeech();
ChatMessageModel chatMessageModel = new ChatMessageModel(reply, "bot");
ref.child("chat").push().setValue(chatMessageModel);
}
#Override
public void onError(AIError error) {
}
#Override
public void onAudioLevel(float level) {
}
#Override
public void onListeningStarted() {
}
#Override
public void onListeningCanceled() {
}
#Override
public void onListeningFinished() {
}}
My Model Class:-
public class ChatMessageModel {
private String msgText;
private String msgUser;
public ChatMessageModel(String msgText, String msgUser){
this.msgText = msgText;
this.msgUser = msgUser;
}
public ChatMessageModel(){
}
public String getMsgText() {
return msgText;
}
public void setMsgText(String msgText) {
this.msgText = msgText;
}
public String getMsgUser() {
return msgUser;
}
public void setMsgUser(String msgUser) {
this.msgUser = msgUser;
}}
My Adapter Class:
public class chat_viewholder extends RecyclerView.ViewHolder {
TextView leftText, rightText;
public chat_viewholder(View itemView) {
super(itemView);
leftText = itemView.findViewById(R.id.leftText);
rightText = itemView.findViewById(R.id.rightText);
}}
Please help me out with this error I am providing the screenshot of the app which I say something or type then the message was not shown in the ScreenShotview.
I'm using a recyclerView that inflates two types of views, to be able to do a chat, everything is fine but it is not sent or received instantly
When I send a message, it is not received unless I click on my edit text,
Which is wrong, because in a chat should show instantly...
My adapter:
public class ChatRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public Context context;
public ArrayList<ChatPersonal> items = new ArrayList<>();
private String mId;
private static final int CHAT_RIGHT = 1;
private static final int CHAT_LEFT = 2;
public ChatRecyclerAdapter (Context context, ArrayList<ChatPersonal> items, String mId){
this.context = context;
this.items = items;
this.mId = mId;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = null;
RecyclerView.ViewHolder holder = null;
switch (viewType){
case CHAT_RIGHT:
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_chat_right, parent, false);
holder = new ChatPersonalHolderSender(view);
break;
case CHAT_LEFT:
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_chat_left, parent, false);
holder = new ChatPersonalHolder(view);
break;
}
return holder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
ChatPersonal mObject = items.get(position);
int itemViewType = getItemViewType(position);
switch(itemViewType){
case CHAT_RIGHT:
((ChatPersonalHolderSender) holder).mMENSAJE.setText(mObject.getMessage());
((ChatPersonalHolderSender) holder).mHORA.setText(DateUtils.getRelativeTimeSpanString(mObject.getHour()));
break;
case CHAT_LEFT:
((ChatPersonalHolder) holder).mMENSAJE.setText(mObject.getMessage());
((ChatPersonalHolder) holder).mHORA.setText(DateUtils.getRelativeTimeSpanString(mObject.getHour()));
break;
}
}
#Override
public int getItemViewType(int position) {
if(items.get(position).getId().equals(mId)){
return CHAT_RIGHT;
}else{
return CHAT_LEFT;
}
}
#Override
public int getItemCount() {
return items.size();
}
}
And this is the relevant code of my chatClass:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
linearLayoutManager = new LinearLayoutManager(ActivityChat.this);
linearLayoutManager.setStackFromEnd(true);
mRecyclerView.setLayoutManager(linearLayoutManager);
mRecyclerView.setHasFixedSize(false);
adapter = new ChatRecyclerAdapter(getApplicationContext(), items, mId);
adapter.notifyDataSetChanged();
mRecyclerView.setAdapter(adapter);
// send message
mSentMensaje.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final String message = mEditText.getText().toString();
if (!message.isEmpty()) {
mChat.setMessage(message);
mChat.setHour(System.currentTimeMillis());
mChat.setId(mId);
if(mUser != null){
if(mUser.getIDchat() != null){
FirebaseUtils.getCHATT(mUser.getIDchat()).push().setValue(mChat).addOnSuccessListener(ActivityChat.this, new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
mRecyclerView.scrollToPosition(items.size() -1);
adapter.notifyDataSetChanged();
mEditText.setText("");
}
});
}}
// retreive message
if(mUser != null){
if(mUser.getIDchat() != null){
FirebaseUtils.getCHATT(mUser.getIDchat()).limitToFirst(50).addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
if (dataSnapshot != null && dataSnapshot.getValue() != null) {
try{
ChatPersonal model = dataSnapshot.getValue(ChatPersonal.class);
items.add(model);
} catch (Exception ex) {
Log.e(TAG, ex.getMessage());
}
}
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
// status
#Override
protected void onStart() {
super.onStart();
adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
#Override
public void onChanged() {
super.onChanged();
mRecyclerView.scrollToPosition(adapter.getItemCount() - 1);
}
});
}
#Override
protected void onResume() {
super.onResume();
adapter.notifyDataSetChanged();
}
#Override
protected void onPostResume() {
super.onPostResume();
adapter.notifyDataSetChanged();
}
}
If you want the data to be synced with Firebase automatically, you need to use FirebaseRecyclerAdapter
Reference: https://github.com/firebase/FirebaseUI-Android/blob/master/database/src/main/java/com/firebase/ui/database/FirebaseRecyclerAdapter.java