I'm new to android and was developing a quiz game. My problem is that when the second player connects to the game, where the first player is already waiting, the second player's game page closes while the first player doesn't. To manage the player's turn, I created a reference to the "turn" node and then on the "setQuiz()" method I used the reference to retrieve the username of the player who has the turn. Can someone help me? Thank you!
package com.example.genialone;
import android.app.ProgressDialog;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import com.bumptech.glide.Glide;
import com.example.genialone.data.RealtimeDatabase;
import com.example.genialone.model.TurnManager;
import com.example.genialone.model.Utente;
import com.example.genialone.preference.PreferencesManager;
import com.example.genialone.util.RandomCategory;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.MutableData;
import com.google.firebase.database.Query;
import com.google.firebase.database.Transaction;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import de.hdodenhof.circleimageview.CircleImageView;
public class GiocoActivity extends BaseActivity {
private Button next;
private PreferencesManager preferencesManager;
private TextView opponent;
private CircleImageView imageOpponent;
private TextView player;
private CircleImageView imagePlayer;
private ProgressDialog progressDialog;
private FirebaseDatabase database = FirebaseDatabase.getInstance();
private TextView question;
private Button option1, option2, option3, option4;
private String rightAnswer;
private String player1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gioco);
player = findViewById(R.id.player);
imagePlayer = findViewById(R.id.imagePlayer);
opponent = findViewById(R.id.opponent);
imageOpponent = findViewById(R.id.imageOpponent);
question = findViewById(R.id.question);
option1 = findViewById(R.id.option1);
option2 = findViewById(R.id.option2);
option3 = findViewById(R.id.option3);
option4 = findViewById(R.id.option4);
preferencesManager = new PreferencesManager(GiocoActivity.this);
player1 = preferencesManager.getUsername();
next = findViewById(R.id.continuaButton);
next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// next turn
}
});
progressDialog = new ProgressDialog(GiocoActivity.this);
progressDialog.setCancelable(false);
progressDialog.setMessage("In cerca di un avversario...");
progressDialog.show();
startGame();
}
public void loadProfilePhoto(String user, CircleImageView imageProfilePhoto) {
DatabaseReference imageRef = database.getReference("Utenti").child(user);
imageRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String imageUrl = dataSnapshot.child("imagineProfilo").getValue(String.class);
Glide.with(GiocoActivity.this).load(imageUrl)
.placeholder(com.firebase.ui.database.R.drawable.common_google_signin_btn_icon_dark)
.circleCrop()
.error(com.firebase.ui.database.R.drawable.common_google_signin_btn_icon_dark_normal)
.into(imageProfilePhoto);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
// Gestione degli errori
}
});
}
private void startGame() {
player.setText(player1);
loadProfilePhoto(player1, imagePlayer);
DatabaseReference connectionRef = database.getReference("connections");
Query availableConnections = connectionRef.orderByChild("player2").equalTo(null);
availableConnections.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if(snapshot.exists()){
for (DataSnapshot gameSnapshot : snapshot.getChildren()) {
String connectionId = gameSnapshot.getKey();
connectionRef.child(connectionId).child("player2").setValue(player1);
join(connectionId);
break;
}
} else {
DatabaseReference newRef = database.getReference("connections").push();
String connectionId = newRef.getKey();
assignPlayersToGame(connectionId, player1);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
private void join(String connectionId) {
DatabaseReference connectionRef = database.getReference("connections").child(connectionId);
connectionRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
String usernameOpponent = snapshot.child("player1").getValue(String.class);
showInfoOpponent(usernameOpponent);
if (progressDialog.isShowing()) {
progressDialog.dismiss();
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
private String playerTurn;
private String turnKey;
private void assignPlayersToGame(String connectionId, String username) {
DatabaseReference connectionRef = database.getReference("connections").child(connectionId);
DatabaseReference turnRef = database.getReference("turn");
turnKey = turnRef.push().getKey();
Map<String, Object> playerData = new HashMap<>();
playerData.put("player1", username);
connectionRef.updateChildren(playerData);
turnRef.updateChildren(playerData);
connectionRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
String usernameOpponent = snapshot.child("player2").getValue(String.class);
if (usernameOpponent != null) {
showInfoOpponent(usernameOpponent);
if (progressDialog.isShowing()) {
progressDialog.dismiss();
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
private void showInfoOpponent(String username) {
DatabaseReference usersRef = database.getReference("Utenti");
usersRef.child(username).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
Utente opponentInfo = snapshot.getValue(Utente.class);
opponent.setText(opponentInfo.getNomeUtente()); // username
loadProfilePhoto(opponentInfo.getNomeUtente(), imageOpponent); // image profile
loadPage();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
private void setQuiz(String questionD, ArrayList<String> options, String answer) {
DatabaseReference turnRef = database.getReference("turn").child(turnKey);
turnRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
playerTurn = snapshot.child("player1").getValue(String.class);
if (player1.equals(playerTurn)) {
question.setText(questionD);
rightAnswer = answer;
Button[] buttons = {option1, option2, option3, option4};
for (int i = 0; i < options.size(); i++) {
buttons[i].setText(options.get(i));
}
next.setVisibility(View.VISIBLE);
} else {
progressDialog = new ProgressDialog(GiocoActivity.this);
progressDialog.setCancelable(false);
progressDialog.setMessage("Wait...");
progressDialog.show();
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
// Gestione degli errori
}
});
}
private void loadPage() {
DatabaseReference quizRef = database.getReference("Quiz");
String category = RandomCategory.getCategory();
quizRef.child(category).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
int idQuestion = RandomCategory.getQuestion();
String quest = snapshot.child("Domande").child(String.valueOf(idQuestion)).getValue(String.class);
ArrayList<String> options = new ArrayList<>();
for (DataSnapshot opt : snapshot.child("Opzioni").child(String.valueOf(idQuestion)).getChildren()) {
String currentOpt = opt.getValue(String.class);
options.add(currentOpt);
}
String rightA = snapshot.child("Risposta").child(String.valueOf(idQuestion)).getValue(String.class);
setQuiz(quest, options, rightA);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}
Related
Getting this error in my LapitChat App. I am not able to solve this i try to figure out many ways to solve but I am not able to solve this. I added my class code with model and db image.
My firebase structure is
Error I am getting when i click on Friends Fragment.
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.divyanshi.chatapp, PID: 29577
com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.String to type com.divyanshi.chatapp.model.Friends
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertBean(CustomClassMapper.java:436)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(CustomClassMapper.java:232)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertToCustomClass(CustomClassMapper.java:80)
at com.google.firebase.database.DataSnapshot.getValue(DataSnapshot.java:203)
at com.firebase.ui.database.ClassSnapshotParser.parseSnapshot(ClassSnapshotParser.java:29)
at com.firebase.ui.database.ClassSnapshotParser.parseSnapshot(ClassSnapshotParser.java:15)
at com.firebase.ui.common.BaseCachingSnapshotParser.parseSnapshot(BaseCachingSnapshotParser.java:36)
at com.firebase.ui.common.BaseObservableSnapshotArray.get(BaseObservableSnapshotArray.java:52)
at com.firebase.ui.database.FirebaseRecyclerAdapter.getItem(FirebaseRecyclerAdapter.java:109)
at com.firebase.ui.database.FirebaseRecyclerAdapter.onBindViewHolder(FirebaseRecyclerAdapter.java:149)
at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:7065)
at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:7107)
at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:6012)
at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6279)
at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6118)
at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6114)
at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2303)
at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1627)
at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1587)
at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:665)
at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4134)
at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:3851)
at androidx.recyclerview.widget.RecyclerView.consumePendingUpdateOperations(RecyclerView.java:1897)
at androidx.recyclerview.widget.RecyclerView$1.run(RecyclerView.java:414)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:949)
at android.view.Choreographer.doCallbacks(Choreographer.java:761)
at android.view.Choreographer.doFrame(Choreographer.java:693)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:935)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
I/Process: Sending signal. PID: 29577 SIG: 9
FriendsFragment.java
package com.divyanshi.chatapp.fragment;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.divyanshi.chatapp.R;
import com.divyanshi.chatapp.model.Friends;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import com.squareup.picasso.Picasso;
import de.hdodenhof.circleimageview.CircleImageView;
public class FriendsFragment extends Fragment {
private RecyclerView mFriendList;
private FirebaseAuth mAuth;
private DatabaseReference mFriendDatabase;
private DatabaseReference mUserDatabase;
String mCurrent_user_id;
private View mMainView;
public FriendsFragment(){
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mMainView = inflater.inflate(R.layout.friends_fragment, container, false);
mFriendList = mMainView.findViewById(R.id.friends_list);
mAuth = FirebaseAuth.getInstance();
mCurrent_user_id = mAuth.getCurrentUser().getUid();
mFriendDatabase = FirebaseDatabase.getInstance().getReference().child("Friends").child(mCurrent_user_id);
mUserDatabase = FirebaseDatabase.getInstance().getReference().child("users");
mFriendList.setHasFixedSize(true);
mFriendList.setLayoutManager(new LinearLayoutManager(getContext()));
return mMainView;
}
#Override
public void onStart() {
super.onStart();
FirebaseRecyclerOptions<Friends> friendsFirebaseRecyclerOptions =
new FirebaseRecyclerOptions.Builder<Friends>()
.setQuery(mFriendDatabase, Friends.class)
.build();
FirebaseRecyclerAdapter<Friends, FriendsViewHolder> adapter = new FirebaseRecyclerAdapter
<Friends, FriendsFragment.FriendsViewHolder>(friendsFirebaseRecyclerOptions) {
#Override
protected void onBindViewHolder(final FriendsViewHolder holder, int position, #NonNull Friends model) {
String list_user_id = getRef(position).getKey();
mUserDatabase.child(list_user_id).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String username = dataSnapshot.child("name").getValue().toString();
String status = dataSnapshot.child("status").getValue().toString();
String thumb_image = dataSnapshot.child("thumb_image").getValue().toString();
holder.tv_usersSingle_username.setText(username);
holder.tv_usersSingle_status.setText(status);
if (!thumb_image.equals("default")) {
Picasso.with(getContext()).load(thumb_image).placeholder(R.mipmap.ic_launcher_round).into(holder.iv_usersSingle_image);
}
Log.d("Special", "I am log name" );
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
#Override
public FriendsFragment.FriendsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.users_single_layout, parent, false);
return new FriendsViewHolder(view);
}
};
mFriendList.setAdapter(adapter);
adapter.startListening();
}
public static class FriendsViewHolder extends RecyclerView.ViewHolder {
private TextView tv_usersSingle_username, tv_usersSingle_status;
private CircleImageView iv_usersSingle_image;
public FriendsViewHolder(#NonNull View itemView) {
super(itemView);
tv_usersSingle_username = itemView.findViewById(R.id.user_single_name);
tv_usersSingle_status = itemView.findViewById(R.id.user_single_status);
iv_usersSingle_image = itemView.findViewById(R.id.user_single_image);
}
}
}
Friends.java Model
package com.divyanshi.chatapp.model;
public class Friends {
public String name, image, status, date;
public Friends() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
}
ProfileActivity.java
package com.divyanshi.chatapp;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.app.ProgressDialog;
import android.os.Bundle;
import java.text.DateFormat;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import com.squareup.picasso.Picasso;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class ProfileActivity extends AppCompatActivity {
private ImageView mProfileImage;
private TextView mProfileName, mProfileStatus, mProfileFriendsCount;
private Button mProfileSendReqBtn, nDeclineBtn;
private DatabaseReference mUserDatabase;
private ProgressDialog mProgressDialog;
private DatabaseReference mFriendReqDatabase;
private DatabaseReference mFriendsDatabase;
private DatabaseReference mNotificationDatabase;
private DatabaseReference mRootRef;
private FirebaseUser mCurrent_user;
private String mCurrent_State;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
final String user_id = getIntent().getStringExtra("user_id");
mUserDatabase = FirebaseDatabase.getInstance().getReference().child("users").child(user_id);
mFriendReqDatabase = FirebaseDatabase.getInstance().getReference().child("Friend_req");
mNotificationDatabase = FirebaseDatabase.getInstance().getReference().child("notification");
mCurrent_user = FirebaseAuth.getInstance().getCurrentUser();
mFriendsDatabase = FirebaseDatabase.getInstance().getReference().child("Friends");
mRootRef=FirebaseDatabase.getInstance().getReference();
mProfileImage = (ImageView) findViewById(R.id.profile_image);
mProfileName = (TextView) findViewById(R.id.profile_display_name);
mProfileStatus = (TextView) findViewById(R.id.profile_status);
mProfileFriendsCount = (TextView) findViewById(R.id.Profile_totalFrnds);
mProfileSendReqBtn = (Button) findViewById(R.id.profile_SendReq);
nDeclineBtn = (Button) findViewById(R.id.profile_Decline_reqBtn);
mCurrent_State = "not_friends";
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setTitle("Loading UserData");
mProgressDialog.setMessage("Please wait while we load the data.");
mProgressDialog.setCanceledOnTouchOutside(false);
mProgressDialog.show();
mUserDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
String display_name = snapshot.child("name").getValue().toString();
String status = snapshot.child("status").getValue().toString();
String image = snapshot.child("image").getValue().toString();
mProfileName.setText(display_name);
mProfileStatus.setText(status);
Picasso.with(ProfileActivity.this).load(image).placeholder(R.drawable.default_avatar).into(mProfileImage);
//-------FRIEND LIST /REQUEST FEATURE--------//
mFriendReqDatabase.child(mCurrent_user.getUid()).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.hasChild(user_id)) {
String req_type = snapshot.child(user_id).child("request_type").getValue().toString();
if (req_type.equals("received")) {
mCurrent_State = "req_received";
mProfileSendReqBtn.setText("Accept Friend Request");
nDeclineBtn.setVisibility(View.VISIBLE);
nDeclineBtn.setEnabled(true);
} else if (req_type.equals("sent")) {
mCurrent_State = "Req_sent";
mProfileSendReqBtn.setText("Cancel Friend Request");
nDeclineBtn.setVisibility(View.INVISIBLE);
nDeclineBtn.setEnabled(false);
}
mProgressDialog.dismiss();
} else {
mFriendsDatabase.child(mCurrent_user.getUid()).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.hasChild(user_id)) {
mCurrent_State = "friends";
mProfileSendReqBtn.setText("Unfriend this Person");
nDeclineBtn.setVisibility(View.INVISIBLE);
nDeclineBtn.setEnabled(false);
}
mProgressDialog.dismiss();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
mProfileSendReqBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mProfileSendReqBtn.setEnabled(false);
// NOT FRIEND STATE//
if (mCurrent_State.equals("not_friends")) {
mFriendReqDatabase.child(mCurrent_user.getUid()).child(user_id).child("request_type").setValue("sent").addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
mFriendReqDatabase.child(user_id).child(mCurrent_user.getUid()).child("request_type").setValue("received").addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
HashMap<String, String> notificationData = new HashMap<>();
notificationData.put("from", mCurrent_user.getUid());
notificationData.put("type", "request");
mNotificationDatabase.child(user_id).push().setValue(notificationData).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
mCurrent_State = "Req_sent";
mProfileSendReqBtn.setText("Cancel Friend Request");
nDeclineBtn.setVisibility(View.INVISIBLE);
nDeclineBtn.setEnabled(false);
}
});
// Toast.makeText(ProfileActivity.this, "Request Sent Successfully.", Toast.LENGTH_SHORT).show();
}
});
} else {
Toast.makeText(ProfileActivity.this, "Failed to send the Request, Please try again.", Toast.LENGTH_SHORT).show();
}
mProfileSendReqBtn.setEnabled(true);
}
});
}
// Cancel the request //
if (mCurrent_State.equals("Req_sent")) {
mFriendReqDatabase.child(mCurrent_user.getUid()).child(user_id).removeValue().addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
mFriendReqDatabase.child(user_id).child(mCurrent_user.getUid()).removeValue().addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
mProfileSendReqBtn.setEnabled(true);
mCurrent_State = "not_friends";
mProfileSendReqBtn.setText("Send Friend Request");
nDeclineBtn.setVisibility(View.INVISIBLE);
nDeclineBtn.setEnabled(false);
}
});
}
});
}
if (mCurrent_State.equals("req_received")){
final String currentDate=DateFormat.getDateTimeInstance().format(new Date());
Map friendMap = new HashMap();
friendMap.put("Friends/"+mCurrent_user.getUid()+"/"+user_id+"/date",currentDate);
friendMap.put("Friends/"+user_id+"/"+mCurrent_user.getUid()+"/date",currentDate);
friendMap.put("Friend_req/"+mCurrent_user.getUid()+"/"+user_id,null);
friendMap.put("Friend_req/"+user_id+"/"+mCurrent_user.getUid(),null);
mRootRef.updateChildren(friendMap, new DatabaseReference.CompletionListener() {
#Override
public void onComplete(#Nullable DatabaseError error, #NonNull DatabaseReference ref) {
mProfileSendReqBtn.setEnabled(true);
mCurrent_State = "friends";
mProfileSendReqBtn.setText("UnFriend this person");
}
});
}
}
});
}
}
com.google.firebase.database.DatabaseException: Can't convert object of
type java.lang.String to type com.divyanshi.chatapp.model.Friends
The exception tells you that you are trying to convert an object of type String into Friends
Looking into code, where you receive firebase dataSanpshot object, you are trying this conversion in below snippet:
String username = dataSnapshot.child("name").getValue().toString();
String status = dataSnapshot.child("status").getValue().toString();
String thumb_image = dataSnapshot.child("thumb_image").getValue().toString();
dataSnapshot.child("name").getValue() should be returning a Friends object, and Because you call toString(), you are trying to convert it to a String, and hence the exception is raised.
To solve this, you can iterate over dataSnapshot children, get a Friends object each time, and extract its data using its getters.
So, to solve this, change onBindViewHolder to below:
#Override
protected void onBindViewHolder(final FriendsViewHolder holder, int position, #NonNull Friends model) {
String list_user_id = getRef(position).getKey();
mUserDatabase.child(list_user_id).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot singleSnapshot : dataSnapshot.getChildren()) {
Friends friend = singleSnapshot.getValue(Friends.class);
String username = friend.getName();
String status = friend.getStatus();
String thumb_image = friend.getImage();
holder.tv_usersSingle_username.setText(username);
holder.tv_usersSingle_status.setText(status);
if (!thumb_image.equals("default")) {
Picasso.with(getContext()).load(thumb_image).placeholder(R.mipmap.ic_launcher_round).into(holder.iv_usersSingle_image);
}
Log.d("Special", "I am log name" );
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
The problem is that your database structure returns a string not an object. You are essentially trying to convert the single key value pair "sd7f57sf7s6sd89f79s":"your_date_here" to Friends.class which is impossible.
You should check out the following link. it should help you know how to save an object into RTdB. Make sure to follow along.
Saving and Retrieving data from Realtime Database
Convert
mFriendDatabase = FirebaseDatabase.getInstance().getReference().child("Friends").child(mCurrent_user_id);
into
mFriendDatabase = FirebaseDatabase.getInstance().getReference("/Friends");
The data that you have under each /Friends/$uid/$otheruid node is a key with a single string value. This does not match the fields/properties of the Friends class, so that's why you get an error.
My guess is that you have the JSON with the properties for each user under /users, and want the recycler view to show the properties from there. If that's the case you have to tell the adapter to look up the data for each, as shown in the FirebaseUI documentation on showing indexed data.
FirebaseRecyclerOptions<Friends> friendsFirebaseRecyclerOptions =
new FirebaseRecyclerOptions.Builder<Friends>()
.setIndexedQuery(mFriendDatabase, mUserDatabase, Friends.class)
.build();
I was putting wrong pair of userid:date. that's why error is coming. I solved it by putting date in next row. Below code I used to solve.
package com.divyanshi.chatapp;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.app.ProgressDialog;
import android.os.Bundle;
import java.text.DateFormat;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import com.squareup.picasso.Picasso;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class ProfileActivity extends AppCompatActivity {
private ImageView mProfileImage;
private TextView mProfileName, mProfileStatus, mProfileFriendsCount;
private Button mProfileSendReqBtn, nDeclineBtn;
private DatabaseReference mUserDatabase;
private ProgressDialog mProgressDialog;
private DatabaseReference mFriendReqDatabase;
private DatabaseReference mFriendsDatabase;
private DatabaseReference mNotificationDatabase;
private DatabaseReference mRootRef;
private FirebaseUser mCurrent_user;
private String mCurrent_State;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
final String user_id = getIntent().getStringExtra("user_id");
mUserDatabase = FirebaseDatabase.getInstance().getReference().child("users").child(user_id);
mFriendReqDatabase = FirebaseDatabase.getInstance().getReference().child("Friend_req");
mNotificationDatabase = FirebaseDatabase.getInstance().getReference().child("notification");
mCurrent_user = FirebaseAuth.getInstance().getCurrentUser();
mFriendsDatabase = FirebaseDatabase.getInstance().getReference().child("Friends");
mRootRef = FirebaseDatabase.getInstance().getReference();
mProfileImage = (ImageView) findViewById(R.id.profile_image);
mProfileName = (TextView) findViewById(R.id.profile_display_name);
mProfileStatus = (TextView) findViewById(R.id.profile_status);
mProfileFriendsCount = (TextView) findViewById(R.id.Profile_totalFrnds);
mProfileSendReqBtn = (Button) findViewById(R.id.profile_SendReq);
nDeclineBtn = (Button) findViewById(R.id.profile_Decline_reqBtn);
mCurrent_State = "not_friends";
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setTitle("Loading UserData");
mProgressDialog.setMessage("Please wait while we load the data.");
mProgressDialog.setCanceledOnTouchOutside(false);
mProgressDialog.show();
mUserDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
String display_name = snapshot.child("name").getValue().toString();
String status = snapshot.child("status").getValue().toString();
String image = snapshot.child("image").getValue().toString();
mProfileName.setText(display_name);
mProfileStatus.setText(status);
Picasso.with(ProfileActivity.this).load(image).placeholder(R.drawable.default_avatar).into(mProfileImage);
//-------FRIEND LIST /REQUEST FEATURE--------//
mFriendReqDatabase.child(mCurrent_user.getUid()).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.hasChild(user_id)) {
String req_type = snapshot.child(user_id).child("request_type").getValue().toString();
if (req_type.equals("received")) {
mCurrent_State = "req_received";
mProfileSendReqBtn.setText("Accept Friend Request");
nDeclineBtn.setVisibility(View.VISIBLE);
nDeclineBtn.setEnabled(true);
} else if (req_type.equals("sent")) {
mCurrent_State = "Req_sent";
mProfileSendReqBtn.setText("Cancel Friend Request");
nDeclineBtn.setVisibility(View.INVISIBLE);
nDeclineBtn.setEnabled(false);
}
mProgressDialog.dismiss();
} else {
mFriendsDatabase.child(mCurrent_user.getUid()).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.hasChild(user_id)) {
mCurrent_State = "friends";
mProfileSendReqBtn.setText("Unfriend this Person");
nDeclineBtn.setVisibility(View.INVISIBLE);
nDeclineBtn.setEnabled(false);
}
mProgressDialog.dismiss();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
mProfileSendReqBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mProfileSendReqBtn.setEnabled(false);
// NOT FRIEND STATE//
if (mCurrent_State.equals("not_friends")) {
mFriendReqDatabase.child(mCurrent_user.getUid()).child(user_id).child("request_type").setValue("sent").addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
mFriendReqDatabase.child(user_id).child(mCurrent_user.getUid()).child("request_type").setValue("received").addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
HashMap<String, String> notificationData = new HashMap<>();
notificationData.put("from", mCurrent_user.getUid());
notificationData.put("type", "request");
mNotificationDatabase.child(user_id).push().setValue(notificationData).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
mCurrent_State = "Req_sent";
mProfileSendReqBtn.setText("Cancel Friend Request");
nDeclineBtn.setVisibility(View.INVISIBLE);
nDeclineBtn.setEnabled(false);
}
});
}
});
} else {
Toast.makeText(ProfileActivity.this, "Failed to send the Request, Please try again.", Toast.LENGTH_SHORT).show();
}
mProfileSendReqBtn.setEnabled(true);
}
});
}
// Cancel the request //
if (mCurrent_State.equals("Req_sent")) {
mFriendReqDatabase.child(mCurrent_user.getUid()).child(user_id).removeValue().addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
mFriendReqDatabase.child(user_id).child(mCurrent_user.getUid()).removeValue().addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
mProfileSendReqBtn.setEnabled(true);
mCurrent_State = "not_friends";
mProfileSendReqBtn.setText("Send Friend Request");
nDeclineBtn.setVisibility(View.INVISIBLE);
nDeclineBtn.setEnabled(false);
}
});
}
});
}
if (mCurrent_State.equals("req_received")) {
final String currentDate = DateFormat.getDateTimeInstance().format(new Date());
Map friendMap = new HashMap();
friendMap.put("Friends/" + mCurrent_user.getUid() + "/" + user_id + "/date", currentDate);
friendMap.put("Friends/" + user_id + "/" + mCurrent_user.getUid() + "/date", currentDate);
friendMap.put("Friend_req/" + mCurrent_user.getUid() + "/" + user_id, null);
friendMap.put("Friend_req/" + user_id + "/" + mCurrent_user.getUid(), null);
mRootRef.updateChildren(friendMap, new DatabaseReference.CompletionListener() {
#Override
public void onComplete(#Nullable DatabaseError error, #NonNull DatabaseReference ref) {
mProfileSendReqBtn.setEnabled(true);
mCurrent_State = "friends";
mProfileSendReqBtn.setText("UnFriend this person");
}
});
}
}
});
}
}
I want to delete the TextView string value from the firebase database which after deleting will return the value as true. How can we then integrate more qr code values under the same key qrCode as shown in the image below.
Image for database :
Basically a qr code scanner will be inbuilt in this app which will give us the string value in TextView field which we want to verify with our database on firebase.
package com.vidmun.dhananjay.qrscanner;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
public class MainActivity extends AppCompatActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button delete = (Button) findViewById(R.id.delete);
TextView qrCode = (TextView) findViewById(R.id.qrCode);
delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mainTest();
//Toast.makeText(getApplicationContext() , "Pressed", Toast.LENGTH_LONG).show();
}
});
}
public void mainTest() {
final TextView qrCode = (TextView) findViewById(R.id.qrCode);
final DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference("qrCode");
rootRef.child("qrCode").orderByChild("data").equalTo(String.valueOf(qrCode)).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.hasChild("qrCode/data")) {
dataSnapshot.getRef().removeValue();
Toast.makeText(getApplicationContext() , "Done", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(getApplicationContext() , "Not Done", Toast.LENGTH_LONG).show();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException();
}
});
}
}
The expected output is the execution of the if condition but else condition is being executed.
Try this
private static final String TAG = MainActivity.class.getSimpleName();
// Write a message to the database
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("qrCode");
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myRef.addChildEventListener(new MyChildEventListener());
}
public void deleteValueFromDb(View view){
myRef.child("data").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
dataSnapshot.getRef().removeValue();
}else{
Toast.makeText(getApplicationContext() , "Not Done", Toast.LENGTH_LONG).show();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException();
}
});
}
private class MyChildEventListener implements ChildEventListener {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Log.i(TAG, "childAdded " + dataSnapshot.toString());
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
Log.i(TAG, "childChanged " + dataSnapshot.toString());
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
Log.i(TAG, "childRemoved " + dataSnapshot.toString());
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
Log.i(TAG, "childMoved " + dataSnapshot.toString());
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.i(TAG, "childMoved " + databaseError.getMessage());
}
}
I believe the issue is with the condition you are checking in onDatachange(). Because of the path "qrCode/data" will always return false.
You can change the "data" with your intended value from editText filed.
And also you can use custom callback listener to get notified of the value when removed.
When you execute a query against the Firebase Database, there will potentially be multiple results. So the snapshot contains a list of those results. Even if there is only a single result, the snapshot will contain a list of one result.
You need to handle this list by looping over dataSnapshot.getChildren() in your onDataChange:
final TextView qrCode = (TextView) findViewById(R.id.qrCode);
final DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference("qrCode");
rootRef.orderByChild("data").equalTo(String.valueOf(qrCode)).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
for (DataSnapshot snapshot: dataSnapshot.getChildren()) {
snapshot.getRef().removeValue();
Toast.makeText(getApplicationContext() , "Deleting", Toast.LENGTH_LONG).show();
}
}
else {
Toast.makeText(getApplicationContext() , "Not found", Toast.LENGTH_LONG).show();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException();
}
});
The changes compared to your code:
Removed the child("qrCode") in your query, since you already have that node in rootRef.
We now loop over dataSnapshot.getChildren() to get each individual search result (even if there is only one).
I have the codes below to load and filter the data from Firebase Firestore to a recycle view that Loads all the Filtered data, everything is working fine , but , when I go delete the selected item from the searched list, it does delete from the Firestore data on the web but still loaded by the Search recycle view after been deleted , looks like the Adatper still have the Data and didn't remove it after been deleted , please take a look to the codes Below in both deletenote() and getnotes() methods :-
package com.example.boc.main;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.blogspot.atifsoftwares.animatoolib.Animatoo;
import com.example.boc.PhoneNumbers.NoteRecyclerViewAdapter;
import com.example.boc.PhoneNumbers.ViewNoteDialog;
import com.example.boc.models.Search;
import com.example.boc.search.SearchRecyclerViewAdapter;
import com.example.boc.R;
import com.example.boc.Interface.IMainActivity;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Menu;
import android.view.View;
import android.view.WindowManager;
import android.widget.EditText;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.firestore.CollectionReference;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.Query;
import com.google.firebase.firestore.QueryDocumentSnapshot;
import com.google.firebase.firestore.QuerySnapshot;
import java.util.ArrayList;
import com.example.boc.models.Note;
/**
* Created by User on 5/14/2018.
*/
public class Search_test extends AppCompatActivity implements
View.OnClickListener,
IMainActivity,
SwipeRefreshLayout.OnRefreshListener {
private static final String TAG = "MainActivity";
//Firebase
private FirebaseAuth.AuthStateListener mAuthListener;
//widgets
private FloatingActionButton mFab, mFab2;
private RecyclerView mRecyclerView;
private SwipeRefreshLayout mSwipeRefreshLayout;
public FirebaseFirestore db = FirebaseFirestore.getInstance();
//vars
private View mParentLayout;
private ArrayList<Search> mSearch = new ArrayList<>();
private ArrayList<Note> mNotes = new ArrayList<>();
private DocumentReference noteRef = db.collection("notes").document();
private CollectionReference notesCollectionRef = db.collection("notes");
private NoteRecyclerViewAdapter mNoteRecyclerViewAdapter;
private SearchRecyclerViewAdapter mSearchRecyclerViewAdapter;
private DocumentSnapshot mLastQueriedDocument;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onCreate(savedInstanceState);
setContentView(R.layout.search_recycler);
mParentLayout = findViewById(android.R.id.content);
mRecyclerView = findViewById(R.id.recycler_view_search);
EditText userinput = findViewById(R.id.userInputtxt);
initRecyclerView();
getNotes();
}
#Override
public void onBackPressed() {
super.onBackPressed();
Animatoo.animateFade(Search_test.this); //fire the slide left animation
}
#Override
public boolean onCreatOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.toolbar, menu);
return true;
}
#Override
public void deleteNote(final Note note) {
FirebaseFirestore db = FirebaseFirestore.getInstance();
DocumentReference noteRef = db
.collection("notes").document(note.getNote_id());
noteRef.delete().addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
makeSnackBarMessage("Deleted note");
mRecyclerView.setAdapter(null);// trying to make the recycle view remove the adapter but still loading the old list //
} else {
makeSnackBarMessage("Failed. Check log.");
}
}
});
}
#Override
public void onRefresh() {
}
private void getNotes() {
FirebaseFirestore db = FirebaseFirestore.getInstance();
final EditText userinput = findViewById(R.id.userInputtxt);
CollectionReference notesCollectionRef = db
.collection("notes");
Query notesQuery = null;
if (mLastQueriedDocument != null) {
notesQuery = notesCollectionRef
.orderBy("timestamp", Query.Direction.ASCENDING);
} else {
notesQuery = notesCollectionRef
.orderBy("timestamp", Query.Direction.ASCENDING);
}
notesQuery.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
String data = "";
for (final QueryDocumentSnapshot document : task.getResult()) {
Note note = document.toObject(Note.class);
mNotes.add(note);
if (userinput == null) {
mRecyclerView.setAdapter(null);
}
if (userinput != null) {
userinput.addTextChangedListener(
new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
final String userinputString = userinput.getText().toString();
mSearch.clear();
for (Note note : mNotes) {
if (note.getTitle().contains(userinputString)) {
if (note != null) {
mSearch.add(note);
mSearchRecyclerViewAdapter = new SearchRecyclerViewAdapter(Search_test.this, mSearch);
mRecyclerView.setLayoutManager(new LinearLayoutManager(Search_test.this));
mRecyclerView.setAdapter(mSearchRecyclerViewAdapter);
mSearchRecyclerViewAdapter.notifyDataSetChanged();
}
}
}
}
}
);
}
}
if (task.getResult().size() != 0) {
mLastQueriedDocument = task.getResult().getDocuments()
.get(task.getResult().size() - 1);
}
mSearchRecyclerViewAdapter.notifyDataSetChanged();
} else {
makeSnackBarMessage("Query Failed. Check Logs.");
}
}
});
}
private void initRecyclerView() {
if (mNoteRecyclerViewAdapter == null) {
mSearchRecyclerViewAdapter = new SearchRecyclerViewAdapter(this, mSearch);
}
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.setAdapter(mSearchRecyclerViewAdapter);
}
#Override
public void updateNote(final Note note) {
FirebaseFirestore db = FirebaseFirestore.getInstance();
DocumentReference noteRef = db
.collection("notes")
.document(note.getNote_id());
noteRef.update(
"title", note.getTitle(),
"content", note.getContent(), "pos", note.getpos()
).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
makeSnackBarMessage(" تم تحديث المعلومات");
} else {
makeSnackBarMessage("حدث خطأ , يرجى اعادة المحاولة");
}
}
});
}
#Override
public void onNoteSelected(Note note) {
ViewNoteDialog dialog = ViewNoteDialog.newInstance(note);
dialog.show(getSupportFragmentManager(), getString(R.string.dialog_view_note));
}
#Override
public void createNewNote(String title, String content, String pos) {
FirebaseFirestore db = FirebaseFirestore.getInstance();
String userId = FirebaseAuth.getInstance().getCurrentUser().getUid();
DocumentReference newNoteRef = db
.collection("notes")
.document();
Note note = new Note();
note.setTitle(title);
note.setContent(content);
note.setPos(pos);
note.setNote_id(newNoteRef.getId());
note.setUser_id(userId);
newNoteRef.set(note).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
makeSnackBarMessage("تمت اضافة رقم الهاتف للسجل");
getNotes();
} else {
makeSnackBarMessage(" يوجد خطأ , يرجى اعادة المحاولة");
}
}
});
}
private void makeSnackBarMessage(String message) {
Snackbar.make(mParentLayout, message, Snackbar.LENGTH_SHORT).show();
}
#Override
public void onClick(View view) {
{
}
}
}
From what i can tell you never removed the element from the list(mNotes or mSearch i think) that the adapter uses it as data source.
So even if it's deleted from Firebase it's still in your list.
To update the list either you have to delete the note from mNotes with the position of the note selected followed by calling adapter notifyDatasetChanged().
Or you have to load the list again from DB calling getNotes().
ANSWER 2
Iliked this one more as long as it doesnot load the data again , as getnotes() will add the data back every time the user input a char.
noteRef.delete().addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
makeSnackBarMessage("Deleted fgfff");
mNotes.remove(note);
mSearch.remove(note);
mSearchRecyclerViewAdapter.notifyDataSetChanged();
}
else{
makeSnackBarMessage("Failed. Check log.");
}
}
});
}
ANSWER 1
I got it, thanks for you all for your time, the solution was by clearing both array lists that is loaded with old data and filtered data, then notify the adapter, after that recall the get notes() method to reload the new data from the firebase firestore which does not contain the deleted ones anymore :-
#Override
public void deleteNote(final Note note){
FirebaseFirestore db = FirebaseFirestore.getInstance();
DocumentReference noteRef = db
.collection("notes").document(note.getNote_id());
noteRef.delete().addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
makeSnackBarMessage("Deleted fgfff");
mNotes.clear();
mSearch.clear();
mSearchRecyclerViewAdapter.notifyDataSetChanged();
getNotes();
}
else{
makeSnackBarMessage("Failed. Check log.");
}
}
});
}
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 3 years ago.
I am working on my Android Studio project. What I want to do, is go to the id of the member, then get their name. I will attach my Firebase database picture.
I am not sure what to do. I want to sign in, then go to MenuActivity.java. When I do sign in, it crashes when going to MenuActivity.java The reason I want to get the name from the database is because on the top of the MenuActivity.java, I want it to say "Hello, name!". So I need the name for the individual that is signed in.
I have checked everything. Everything seems confusing and I am currently getting this error.
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.cis436.ewalletprototype, PID: 10053
java.lang.NullPointerException: **Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()'** on a null object reference
at com.cis436.ewalletprototype.MenuActivity$1.onDataChange(MenuActivity.java:66)
at com.google.firebase.database.core.ValueEventRegistration.fireEvent(com.google.firebase:firebase-database##18.0.1:75)
at com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database##18.0.1:63)
at com.google.firebase.database.core.view.EventRaiser$1.run(com.google.firebase:firebase-database##18.0.1:55)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
I/Process: Sending signal. PID: 10053 SIG: 9
Application terminated.
Here is signInActivity.java
package com.cis436.ewalletprototype;
import android.content.Intent;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
public class signInActivity extends AppCompatActivity {
int RC_SIGN_IN = 0;
Button btnSignIn;
Button btnSignUp;
Button btnSignInGoogle;
Button btnSignInFacebook;
EditText txtEmailInput;
EditText txtPasswordInput;
TextView btnForgotPassword;
private FirebaseAuth mAuth;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sign_in);
btnSignIn = findViewById(R.id.btnSignIn);
btnSignUp = findViewById(R.id.sign_up);
btnSignInGoogle = findViewById(R.id.sign_in_google);
btnSignInFacebook = findViewById(R.id.sign_in_facebook);
txtEmailInput = findViewById(R.id.txtEmail);
txtPasswordInput = findViewById(R.id.txtPassword);
btnForgotPassword = findViewById(R.id.txtForgotPassword);
mAuth = FirebaseAuth.getInstance();
//if (mAuth.getCurrentUser() != null) {
// startActivity(new Intent(signInActivity.this, MenuActivity.class));
// finish();
//}
btnSignUp.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(signInActivity.this, signUpActivity.class));
}
});
//Click Listeners for buttons
btnSignIn.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent signUpP2 = new Intent(signInActivity.this,MenuActivity.class);
finish();
startActivity(signUpP2);
}
});
btnSignIn.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
String email = txtEmailInput.getText().toString();
final String password = txtPasswordInput.getText().toString();
if (TextUtils.isEmpty(email)) {
Toast.makeText(getApplicationContext(), "Enter email address!", Toast.LENGTH_SHORT).show();
return;
}
if (TextUtils.isEmpty(password)) {
Toast.makeText(getApplicationContext(), "Enter password!", Toast.LENGTH_SHORT).show();
return;
}
//authenticate user
mAuth.signInWithEmailAndPassword(email, password)
.addOnCompleteListener(signInActivity.this,
new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
// If sign in fails, display a message to the user. If sign in succeeds
// the auth state listener will be notified and logic to handle the
// signed in user can be handled in the listener.
if (!task.isSuccessful())
{
// there was an error
if (password.length() < 6)
{
Toast.makeText(signInActivity.this, "Password must be at least 6 characters", Toast.LENGTH_SHORT).show();
txtPasswordInput.setError(getString(R.string.minimum_password));
}
else
{
Toast.makeText(signInActivity.this, getString(R.string.auth_failed), Toast.LENGTH_LONG).show();
}
}
else
{
if(mAuth.getCurrentUser().isEmailVerified())
{
Toast.makeText(signInActivity.this, "Registered successfully. Please check your email for verification", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(signInActivity.this, MenuActivity.class);
startActivity(intent);
finish();
}
}
}
});
}
});
}
}
Here is MenuActivity.java
package com.cis436.ewalletprototype;
import android.app.Activity;
import android.content.Intent;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.google.firebase.auth.FirebaseAuth;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.navigation.NavigationView;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx;
import java.util.ArrayList;
public class MenuActivity extends Activity {
private static final String TAG = "ViewDatabase";
private DrawerLayout drawer;
private TextView txtWelcomeName;
String mName,mID;
Member member;
long maxid = 0;
private FirebaseDatabase mFirebaseDatabase;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private DatabaseReference myRef;
private String userID;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu);
txtWelcomeName = findViewById(R.id.tb_welcomeMessage);
//declare the database reference object. This is what we use to access the database.
//NOTE: Unless you are signed in, this will not be useable.
mAuth = FirebaseAuth.getInstance();
mFirebaseDatabase = FirebaseDatabase.getInstance();
FirebaseUser user = mAuth.getCurrentUser();
userID = user.getUid();
myRef = FirebaseDatabase.getInstance().getReference().child("Member").child(userID);
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String name = dataSnapshot.child("name").getValue().toString();
txtWelcomeName.setText(name);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
//Bottom Navigation
BottomNavigationViewEx bottomNavigationViewEx = findViewById(R.id.bottom_bar);
bottomNavigationViewEx.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.hamburgerAction:
drawer.openDrawer(GravityCompat.START);
break;
case R.id.reportAction:
Intent report = new Intent(MenuActivity.this, ContactActivity.class);
startActivity(report);
break;
case R.id.notificationsAction:
Intent notifications = new Intent(MenuActivity.this, NotificationsActivity.class);
startActivity(notifications);
break;
case R.id.settingsAction:
Intent settings = new Intent(MenuActivity.this, SettingsActivity.class);
startActivity(settings);
break;
}
return true;
}
});
//Drawer Navigation
drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
switch(menuItem.getItemId()) {
case R.id.dm_profile:
Intent profile = new Intent(MenuActivity.this, ProfileActivity.class);
drawer.closeDrawer(GravityCompat.START);
startActivity(profile);
break;
case R.id.dm_settings:
Intent settings = new Intent(MenuActivity.this, ContactActivity.class);
drawer.closeDrawer(GravityCompat.START);
startActivity(settings);
break;
case R.id.dm_help:
Intent help = new Intent(MenuActivity.this, HelpActivity.class);
drawer.closeDrawer(GravityCompat.START);
startActivity(help);
break;
case R.id.dm_logout:
//Logout of account
break;
}
return true;
}
});
//Main Menu Buttons
Button btnMakePayment = findViewById(R.id.btnMakePayment);
Button btnSendMoney = findViewById(R.id.btnSendMoney);
Button btnContact = findViewById(R.id.btnReport);
Button btnSettings = findViewById(R.id.btnSettings);
Button btnCalendar = findViewById(R.id.btnCalendar);
btnMakePayment.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent makePayment = new Intent(MenuActivity.this, MakePaymentActivity.class);
startActivity(makePayment);
}
});
btnContact.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent contact = new Intent(MenuActivity.this, ContactActivity.class);
startActivity(contact);
}
});
btnSettings.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent settings = new Intent(MenuActivity.this, SettingsActivity.class);
startActivity(settings);
}
});
btnCalendar.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent calendar = new Intent(MenuActivity.this, CalendarActivity.class);
startActivity(calendar);
}
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////
mAuthListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
// User is signed in
Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid());
toastMessage("Successfully signed in with: " + user.getEmail());
} else {
// User is signed out
Log.d(TAG, "onAuthStateChanged:signed_out");
toastMessage("Successfully signed out.");
}
// ...
}
};
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// This method is called once with the initial value and again
// whenever data at this location is updated.
showData(dataSnapshot);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
txtWelcomeName.setText(mName);
}
////////////////////////////////
/////////////////////////////////////
private void showData(DataSnapshot dataSnapshot) {
Member member = dataSnapshot.getValue(Member.class);
mName = member.getName();
txtWelcomeName.setText(mName);
//display all the information
//Log.d(TAG, "showData: name: " + member.getName());
//txtWelcomeName.setText(member.getName());
ArrayList<String> array = new ArrayList<>();
array.add(member.getName());
}
#Override
public void onStart() {
super.onStart();
mAuth.addAuthStateListener(mAuthListener);
}
#Override
public void onStop() {
super.onStop();
if (mAuthListener != null) {
mAuth.removeAuthStateListener(mAuthListener);
}
}
private void toastMessage(String message){
Toast.makeText(this,message,Toast.LENGTH_SHORT).show();
}
#Override
public void onBackPressed() {
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
}
Here is my Member.class
package com.cis436.ewalletprototype;
public class Member {
private String name="";
private String email="";
private String date="";
private String homeAddress="";
private String country="";
private String companyName="";
private String companyAddress="";
private String zipcode="";
private String memberId="";
private String paypalEmail="";
public Member()
{
}
public Member(String memberId, String email, String date, String homeAddress, String country, String companyName, String companyAddress, String zipcode, String paypalEmail, String name)
{
this.memberId = memberId;
this.email = email;
this.name = name;
this.date = date;
this.homeAddress = homeAddress;
this.country = country;
this.companyName = companyName;
this.companyAddress = companyAddress;
this.zipcode = zipcode;
this.paypalEmail = paypalEmail;
}
public String getMemberId() { return memberId; }
public void setMemberId(String memberId) { this.memberId = memberId; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public String getDate() { return date; }
public void setDate(String date) { this.date = date; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getHomeAddress() { return homeAddress; }
public void setHomeAddress(String homeAddress) { this.homeAddress = homeAddress; }
public String getCountry() { return country; }
public void setCountry(String country) { this.email = country; }
public String getCompanyName() { return companyName; }
public void setCompanyName(String companyName) { this.companyName = companyName; }
public String getCompanyAddress() { return companyAddress; }
public void setCompanyAddress(String companyAddress) { this.companyAddress = companyAddress; }
public String getZipcode() { return zipcode; }
public void setZipcode(String zipcode) { this.zipcode = zipcode; }
public String getPaypalEmail() { return paypalEmail; }
public void setPaypalEmail(String paypalEmail) { this.paypalEmail = paypalEmail; }
}
Here is the picture of my current database:
My Database Picture
When using the following lines of code:
FirebaseUser user = mAuth.getCurrentUser();
userID = user.getUid();
The getUid() method will return the id of the authenticated user. When passing that userID to following line:
myRef = FirebaseDatabase.getInstance().getReference().child("Member").child(userID);
It means that you are setting the reference to the user object that has its key the uid that it comes from the authentication process. As I see in your database, the key of the user is not the one above is a random key generated by the push() method, see it is starting with - (minus) sign.
To solve this, you either change that pushed key with the actual user id, which is the recommend solution and which also means that you need to add the user object again to the database or you can use the following query:
Query query = myRef = FirebaseDatabase.getInstance().getReference()
.child("Member")
.orderByChild("memberId")
.equalTo("-LlGrtcsbW6jLWKoLhLw");
And everything else will work perfectly fine.
You can try below.
myRef = FirebaseDatabase.getInstance().getReference().child("Member").child(userID);
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
Member member = dataSnapshot.getValue(Member.class);
String name = member.getName();
txtWelcomeName.setText(name);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
When you use getvalue() function you must pass the class name of the object you want to retrieve the value of. Try the following.
Instead of:
String name = dataSnapshot.child("name").getValue().toString();
You must use:
String name = dataSnapshot.child("name").getValue(String.class);
You can read the firebase documentation for more information.
https://firebase.google.com/docs/database/android/read-and-write
I'm trying to retrieve data from my Firebase Realtime Database but encountering this issue.
I'm suspecting I got this error due to my path in DatabaseReference. I tried different paths but none seemed to work.
Here's my database (The generated texts are userID)
My class that stores the data structure
public class ERDataStructure {
private String temperature;
private String humidity;
public ERDataStructure() {
}
public ERDataStructure(String temperature, String humidity) {
this.temperature = temperature;
this.humidity = humidity;
}
public String getTemperature(){
return temperature;
}
public void setTemperature(String temperature){
this.temperature = temperature;
}
public String getHumidity() {
return humidity;
}
public void setHumidity(String humidity) {
this.humidity = humidity;
}
}
My ReadingScreen.java (MainActivity)
import ...
public class ReadingScreen extends AppCompatActivity {
//Firebase Initialization
FirebaseAuth mAuth;
FirebaseAuth.AuthStateListener mAuthListener;
private DatabaseReference myRef;
private FirebaseDatabase mFirebaseDatabase;
private static final String TAG = "ReadingScreen";
ERDataStructure mData;
private TextView textViewTemperatureNumber, textViewHumidityNumber;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reading_screen);
//Find Views
textViewHumidityNumber = (TextView) findViewById(R.id.humidity_number);
textViewTemperatureNumber = (TextView) findViewById(R.id.temperature_number);
// Initiate Firebase
mAuth = FirebaseAuth.getInstance();
mFirebaseDatabase = FirebaseDatabase.getInstance();
FirebaseUser user = mAuth.getCurrentUser();
String userID = user.getUid();
// Non-working Reference, but code works
//myRef = mFirebaseDatabase.getReference();
//myRef = mFirebaseDatabase.getReference().child(userID);
//Crashing Reference
myRef = mFirebaseDatabase.getReference().child(userID).child("ERDataStructure");
//myRef = mFirebaseDatabase.getReference("ERDataStructure");
//
retrieveData();
}
public void gotoMainMenu (View view)
{
Intent intent = new Intent(ReadingScreen.this, MainMenu.class);
startActivity(intent);
}
private void retrieveData(){
myRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
ERDataStructure ds = dataSnapshot.getValue(ERDataStructure.class);
textViewTemperatureNumber.setText("" +ds.getTemperature());
textViewHumidityNumber.setText(""+ds.getHumidity());
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
ERDataStructure ds = dataSnapshot.getValue(ERDataStructure.class);
textViewTemperatureNumber.setText("" +ds.getTemperature());
textViewHumidityNumber.setText(""+ds.getHumidity());
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
List<ERDataStructure> arraylist = new ArrayList<ERDataStructure>();
if (dataSnapshot != null && dataSnapshot.getValue() != null){
//FirebaseUser user = mAuth.getCurrentUser();
//String userID = user.getUid();
for (DataSnapshot a : dataSnapshot.getChildren()){
ERDataStructure dataStructure = new ERDataStructure();
dataStructure.setTemperature(a.getValue(ERDataStructure.class).getTemperature());
dataStructure.setHumidity(a.getValue(ERDataStructure.class).getHumidity());
arraylist.add(dataStructure);
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
The error was recorded in
ERDataStructure ds = dataSnapshot.getValue(ERDataStructure.class);
Edit: After adding another level to my database, it manages to run
You need to use ValueEventListener instead of ChildEventListener, so change it to this:
myRef = mFirebaseDatabase.getReference().child(userID).child("ERDataStructure");
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
ERDataStructure ds = dataSnapshot.getValue(ERDataStructure.class);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
In this case you use ValueEventListener, because when you use childEventListener you are basically looping inside this snapshot and returning the value of humidity as type String. It is like looping over dataSnapshot.getChildren() in the valueventlistener.