In my ChatListActivity, I am getting emails of users and showing them in a listView using Firebase. There is value in Firebase because when the arraylist is showing its data when I use log, but isn't showing in ListView. Please help.
public class ChatListActivity extends AppCompatActivity {
ListView userListView;
ArrayAdapter<String> arrayAdapter;
ArrayList<String> users = new ArrayList<>();
FirebaseAuth mAuth;
DatabaseReference databaseReference;
Button signOut;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat_list);
mAuth = FirebaseAuth.getInstance();
databaseReference = FirebaseDatabase.getInstance().getReference();
userListView = findViewById(R.id.userListView);
signOut = findViewById(R.id.signOut);
databaseReference.child("users").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.exists()){
for (DataSnapshot dataSnapshot : snapshot.getChildren()){
String email = dataSnapshot.child("email").getValue().toString();
if (!email.equals(FirebaseAuth.getInstance().getCurrentUser().getEmail())){
users.add(email);
Log.i("Log", Arrays.toString(new ArrayList[]{users}));
}
}
arrayAdapter = new ArrayAdapter<>(ChatListActivity.this, android.R.layout.simple_list_item_1, users);
userListView.setAdapter(arrayAdapter);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Toast.makeText(ChatListActivity.this, "Failed to load users", Toast.LENGTH_SHORT).show();
}
});
signOut.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mAuth.signOut();
Intent intent = new Intent(ChatListActivity.this, MainActivity.class);
startActivity(intent);
}
});
}
}
Here is my log.
Do set an empty adapter before network call, like this
arrayAdapter = new ArrayAdapter<>(ChatListActivity.this, android.R.layout.simple_list_item_1, users);
userListView.setAdapter(arrayAdapter);
after you receive original response, reset the adapter with new data. That should work.
now "users" will have some data
arrayAdapter = new ArrayAdapter<>(ChatListActivity.this, android.R.layout.simple_list_item_1, users);
userListView.setAdapter(arrayAdapter);
Related
In my firebase I have questions and their answers stored. Each answer has an id, which it got from push(). But I am unable to show the list of all the users who have answered the question. Please help.
Here is the code:
ListView listView;
ArrayList<String> answerers = new ArrayList<>();
ArrayAdapter arrayAdapter;
String askedBy, question, likes;
FirebaseAuth mAuth;
DatabaseReference databaseReference;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_answers);
listView = findViewById(R.id.answersListView);
Intent intent = getIntent();
askedBy = intent.getStringExtra("askedBy");
question = intent.getStringExtra("question");
likes = intent.getStringExtra("numberOfLikes");
mAuth = FirebaseAuth.getInstance();
databaseReference = FirebaseDatabase.getInstance().getReference();
databaseReference.child("questions").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.exists()){
for (DataSnapshot dataSnapshot : snapshot.getChildren()){
if (dataSnapshot.child("question").getValue().toString().equals(question) && dataSnapshot.child("askedBy").getValue().toString().equals(askedBy)
&& dataSnapshot.child("likes").getValue().toString().equals(likes)) {
dataSnapshot.child("answers").getRef().addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshots) {
if (snapshots.exists()){
for (DataSnapshot dataSnapshots : snapshots.getChildren()){
String id = dataSnapshot.getRef().push().getKey();
answerers.add(dataSnapshots.child(id).child("answeredBy").getValue().toString());
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
arrayAdapter = new ArrayAdapter<>(ViewAnswersActivity.this, android.R.layout.simple_list_item_1, answerers);
listView.setAdapter(arrayAdapter);
}
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Intent intent1 = new Intent(ViewAnswersActivity.this, AnswerActivity.class);
intent1.putExtra("askedBy", askedBy);
intent1.putExtra("answeredBy", answerers.get(i));
intent1.putExtra("question", question);
intent1.putExtra("numberOfLikes", likes);
startActivity(intent1);
}
});
}
When I am running the app, the listView is coming empty, indicating value hasn't been stored.
Try to set adapter within onDataChange()
#Override
public void onDataChange(#NonNull DataSnapshot snapshots) {
if (snapshots.exists()){
for (DataSnapshot dataSnapshots : snapshots.getChildren()){
String id = dataSnapshot.getRef().push().getKey();
answerers.add(dataSnapshots.child(id).child("answeredBy").getValue().toString());
}
arrayAdapter = new ArrayAdapter<> (ViewAnswersActivity.this, android.R.layout.simple_list_item_1, answerers);
listView.setAdapter(arrayAdapter);
}
}
I have this problem when i open the view of "Eventos", im trying to delete from de database the selected items from the listview.
public class ShowData extends AppCompatActivity {
DatabaseReference databaseReference;
ListView listView;
ArrayList<String> arrayList = new ArrayList<>();
ArrayAdapter<String> arrayAdapter;
Button btnDelete;
Module module;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_data);
databaseReference = FirebaseDatabase.getInstance().getReference("Eventos");
listView = (ListView) findViewById(R.id.listViewShow);
btnDelete = (Button) findViewById(R.id.btnBorrarElemento);
module=((Module)getApplication());
arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, arrayList);
listView.setAdapter(arrayAdapter); .....
... listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> paramAdapterView, View view, int position, long id) {
module.setGvalue_titulo(arrayList.get(position));
module.setGvalue_descripcion(arrayList.get(position));
module.setGvalue_fecha(arrayList.get(position));
module.setGvalue_url(arrayList.get(position));
}
});
btnDelete.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
final String str = module.getGvalue_titulo().substring(0, 6);
if(str == ""){
Toast.makeText(ShowData.this, "No se ha seleccionado ningun elemento para eliminar", Toast.LENGTH_SHORT).show();
}
else {
databaseReference.child("Eventos").child(str).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
databaseReference.child(str).removeValue();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
Toast.makeText(ShowData.this, "Evento Eliminado", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(getApplicationContext(),ShowData.class);
startActivity(intent);
}
}
}); ....
The module has the getters and setters necessaries:
In my manifest, I have this:
Your problem is that you are trying to cast your Application to Module, but it's not Module. Well, have you registered your Module as custom application implementation in your AndroidManifest.xml? If the answer is "no" than this is the exact reason! Follow this answer to check how to do it easily.
I'm trying to return the key and value from my Firebase Database and insert it into a RecycleView adapter but the values won't show up in the app.
I can't wrap my head around this whatsoever.
I tried to show the values in a Toast and it worked but why won't the values be inserted into the RecycleView adapter?
This is the code.
public class test extends AppCompatActivity {
TextView textView;
Button button;
String phone;
String n;
String a;
FirebaseAuth mAuth;
MyRecyclerViewAdapter adapter;
ArrayList<String> info;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
Bundle b = new Bundle();
b = getIntent().getExtras();
phone = b.getString("number");
textView = findViewById(R.id.textV);
button = findViewById(R.id.signoutButton);
mAuth = FirebaseAuth.getInstance();
textView.setText(textView.getText().toString() + " as " + phone);
info = new ArrayList<>();
FirebaseDatabase myRef = FirebaseDatabase.getInstance();
DatabaseReference sRef = myRef.getReference("users");
sRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot childSnap : dataSnapshot.getChildren()) {
if (childSnap.getKey().equals(phone)) {
for (DataSnapshot c : childSnap.getChildren()) {
n = c.getKey();
a = c.getValue().toString();
info.add(n);
info.add(a);
}
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
RecyclerView recyclerView = findViewById(R.id.rvInfo);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new MyRecyclerViewAdapter(this, info);
adapter.setClickListener(new MyRecyclerViewAdapter.ItemClickListener() {
#Override
public void onItemClick(View view, int position) {
Toast.makeText(test.this, "You clicked " + adapter.getItem(position) + " on row number " + position, Toast.LENGTH_SHORT).show();
}
});
recyclerView.setAdapter(adapter);
}
}
You can get this using following code
sRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot childSnap : dataSnapshot.getChildren()) {
if (childSnap.getKey().equals(phone)) {
for (DataSnapshot c : childSnap.getChildren()) {
n = c.getKey();
a = c.getValue().toString();
info.add(n);
info.add(a);
}
}
}
notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
You have to add notifyDataSetChanged(); after you fill ArrayList from firebase. Because it's take time to load data from firebase. And your adapter initialised before fill ArrayList from firebase.
Here is the image of my Firebase database setup:
I'm trying to program a simple notes application, I'm able to save everything to Firebase but struggling to retrieve the information.
A child of the user IDis randomly generated which is causing me issues when trying to retrieve the data. The below code is how im saving all the data to the Firebase database.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_progress_reports);
findViewById(R.id.saveNoteButton).setOnClickListener(saveReport);
progressReportTitle = findViewById(R.id.progressReportTitle);
progressReportContent = findViewById(R.id.progressReportContent);
fAuth = FirebaseAuth.getInstance();
fProgressReportsDatabase = FirebaseDatabase.getInstance().getReference().child("ProgressReports").child(fAuth.getCurrentUser().getUid());
findViewById(R.id.loadNoteButton).setOnClickListener(loadReports);
}
View.OnClickListener saveReport = new View.OnClickListener() {
#Override
public void onClick(View v) {
String title = progressReportTitle.getText().toString().trim();
String content = progressReportContent.getText().toString().trim();
if (title.isEmpty()) {
progressReportTitle.setError("Please Enter a title for this report");
progressReportTitle.requestFocus();
} else if (content.isEmpty()) {
progressReportContent.setError("No content within report");
progressReportContent.requestFocus();
} else {
saveReportToDB(title, content);
}
}
};
private void saveReportToDB(String title, String content) {
if (fAuth.getCurrentUser() != null) {
final DatabaseReference newProgressReportRef = fProgressReportsDatabase.push();
final Map progressReportMap = new HashMap();
progressReportMap.put("title", title);
progressReportMap.put("content", content);
progressReportMap.put("timestamp", ServerValue.TIMESTAMP);
And below is how im attempting to load this data into a listview on a separate activity, with no luck,
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_view);
mListView = (findViewById(R.id.progressList));
fAuth = FirebaseAuth.getInstance();
fFirebaseDatabase = FirebaseDatabase.getInstance();
myRef = FirebaseDatabase.getInstance().getReference().child("ProgressReports").child(fAuth.getCurrentUser().getUid());;
FirebaseUser user = fAuth.getCurrentUser();
userID = user.getUid();
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
showData(dataSnapshot);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
private void showData(DataSnapshot dataSnapshot){
for(DataSnapshot ds : dataSnapshot.getChildren()){
ReportInformation rInfo = new ReportInformation();
rInfo.setTitle(ds.child(userID).child("title").getValue(ReportInformation.class).getTitle());
rInfo.setContent(ds.child(userID).child("content").getValue(ReportInformation.class).getContent());
//rInfo.setTimestamp(ds.child(userID).child("timestamp").getValue().toString());
ArrayList<String> array = new ArrayList<>();
array.add(rInfo.getTitle());
array.add(rInfo.getContent());
//array.add(rInfo.getTimestamp());
ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, array);
mListView.setAdapter(adapter);
}
}
What am I doing wrong, and how can I query the database for the HashMap which is randomly generated?
Thanks guys
To display all titles of all those objects in a ListView, please use the following lines of code:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference uidRef = rootRef.child("ProgressReports").child(uid);
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
List<String> list = new ArrayList<>();
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String title = ds.child("title").getValue(String.class);
list.add(title);
Log.d("TAG", title);
}
ListView listView = (ListView) findViewById(R.id.list_view);
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, list);
listView.setAdapter(arrayAdapter);
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
uidRef.addListenerForSingleValueEvent(eventListener);
Your list will contain two titles:
Test
Test
More information here if you want to use a model class.
I'm building a simple chat application. In user fragment, if we click on user it get crashed and go to previous activity if there is previous chat. While there is no chat with that user fragment works fine, but when we type message and click send message store on Firebase and app crashes, similarly if there is chat, chat fragment get crashed.
I think problem is in mReference.addValueEventListener(new ValueEventListener()) method. Code and error is given below. I saw other answers but didn't understand with my code.
MessageActivity.java
public class MessageActivity extends AppCompatActivity {
CircleImageView profile_image;
TextView username;
FirebaseUser mFirebaseUser;
DatabaseReference mDatabaseReference;
ImageView btn_send;
EditText send_msg;
Intent mIntent;
MessageAdapter mMessageAdapter;
List<Chat> mChats;
RecyclerView mRecyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_message);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
finish();
}
});
profile_image = findViewById(R.id.profile_image);
username = findViewById(R.id.username);
btn_send = findViewById(R.id.img_btn_send);
send_msg = findViewById(R.id.text_send);
mRecyclerView = findViewById(R.id.recycler_view);
mRecyclerView.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getApplicationContext());
linearLayoutManager.setStackFromEnd(true);
mRecyclerView.setLayoutManager(linearLayoutManager);
mIntent = getIntent();
final String userid = mIntent.getStringExtra("userid");
mFirebaseUser = FirebaseAuth.getInstance().getCurrentUser();
mDatabaseReference = FirebaseDatabase.getInstance().getReference("Users").child(userid);
btn_send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String msg = send_msg.getText().toString();
if (!msg.equals("")){
sendMessage(mFirebaseUser.getUid(), userid, msg);
}
send_msg.setText("");
}
});
mDatabaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
assert user != null;
username.setText(user.getUsername());
if ( user.getImageURL().equals("default")){
profile_image.setImageResource(R.mipmap.ic_launcher_round);
}else {
Glide.with(MessageActivity.this).load(user.getImageURL()).into(profile_image);
}
readMessage(mFirebaseUser.getUid(), userid, user.getImageURL());
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
private void sendMessage(String sender, String receiver, String message){
DatabaseReference mDatabaseReference = FirebaseDatabase.getInstance().getReference();
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("sender", sender);
hashMap.put("receiver", receiver);
hashMap.put("message", message);
mDatabaseReference.child("Chats").setValue(hashMap);
}
private void readMessage(final String myId, final String userID, final String imageURL){
mChats = new ArrayList<>();
mDatabaseReference = FirebaseDatabase.getInstance().getReference("Chats");
mDatabaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
mChats.clear();
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()){
Chat chat = dataSnapshot1.getValue(Chat.class);
assert chat != null;
if (chat.getReceiver().equals(myId) && chat.getSender().equals(userID) || chat.getReceiver().equals(userID) && chat.getSender().equals(myId)){
mChats.add(chat);
}
mMessageAdapter = new MessageAdapter(MessageActivity.this, mChats, imageURL);
mRecyclerView.setAdapter(mMessageAdapter);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
ChatsFragment.java
public class ChatsFragment extends Fragment {
private RecyclerView mRecyclerView;
private UserAdapter mUserAdapter;
private List<User> mUsers;
FirebaseUser fUser;
DatabaseReference mReference;
private List<String> userList;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_chats, container, false);
mRecyclerView = view.findViewById(R.id.recycler_view);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
fUser = FirebaseAuth.getInstance().getCurrentUser();
userList = new ArrayList<>();
mReference = FirebaseDatabase.getInstance().getReference("Chats");
mReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
userList.clear();
for (DataSnapshot snapshot: dataSnapshot.getChildren()){
Chat chat = snapshot.getValue(Chat.class);
if (chat.getSender().equals(fUser.getUid())){
userList.add(chat.getReceiver());
}
if (chat.getReceiver().equals(fUser.getUid())){
userList.add(chat.getSender());
}
}
readChats();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
return view;
}
private void readChats() {
mUsers = new ArrayList<>();
mReference = FirebaseDatabase.getInstance().getReference("Users");
mReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
mUsers.clear();
for (DataSnapshot snapshot: dataSnapshot.getChildren()){
User user = snapshot.getValue(User.class);
for (String id : userList){
if (user.getId().equals(id)){
if (mUsers.size() != 0){
for ( User user1 : mUsers){
if ( !user.getId().equals(user1.getId()));
mUsers.add(user);
}
}
else{
mUsers.add(user);
}
}
}
}
mUserAdapter = new UserAdapter(getContext(), mUsers);
mRecyclerView.setAdapter(mUserAdapter);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
Error is :
com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.String to type
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertBean(com.google.firebase:firebase-database##16.0.4:423)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(com.google.firebase:firebase-database##16.0.4:214)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertToCustomClass(com.google.firebase:firebase-database##16.0.4:79)
at com.google.firebase.database.DataSnapshot.getValue(com.google.firebase:firebase-database##16.0.4:212)
at com.google.firebase.database.core.ValueEventRegistration.fireEvent(com.google.firebase:firebase-database##16.0.4:75)
at com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database##16.0.4:63)
at com.google.firebase.database.core.view.EventRaiser$1.run(com.google.firebase:firebase-database##16.0.4:55)
at android.os.Handler.handleCallback(Handler.java:754)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:163)
at android.app.ActivityThread.main(ActivityThread.java:6228)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)