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.");
}
}
});
}
Related
Login.java
package com.example.simpleaccounting;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.Manifest;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
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.FirebaseApp;
import com.google.firebase.FirebaseException;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.auth.PhoneAuthCredential;
import com.google.firebase.auth.PhoneAuthOptions;
import com.google.firebase.auth.PhoneAuthProvider;
import com.google.zxing.pdf417.encoder.PDF417;
import java.util.concurrent.TimeUnit;
public class Login extends AppCompatActivity {
private EditText countryCodeEdit, phoneNumberEdit;
private Button mSendOTPBtn;
ProgressDialog progressDialog;
TextView processText;
private FirebaseAuth auth;
private PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallBacks;
private Boolean authFlag = false;
//permission constants
private static final int CAMERA_REQUEST_CODE = 100;
private static final int STORAGE_REQUEST_CODE = 101;
//image pick constants
private static final int IMAGE_PICK_CAMERA_CODE = 102;
private static final int IMAGE_PICK_GALLERY_CODE = 103;
//arrays of permissions
private String[] cameraPermissions; //camera and storage
private String[] storagePermissions; // only storage
//variables (will contain data to save)
private Uri imageUri;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
mSendOTPBtn = findViewById(R.id.send_codebtn);
processText = findViewById(R.id.text_process);
countryCodeEdit = findViewById(R.id.input_country_code);
phoneNumberEdit = findViewById(R.id.input_phone);
//init permission arrays
cameraPermissions = new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE};
requestCameraPermission();
//set by default text for country code
countryCodeEdit.setText("91");
auth = FirebaseAuth.getInstance();
mSendOTPBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//initialize progress dialog
progressDialog = new ProgressDialog(Login.this);
//show progress dialog
progressDialog.show();
//set Content View
progressDialog.setContentView(R.layout.progress_dialog);
//set transparent background
progressDialog.getWindow().setBackgroundDrawableResource(
android.R.color.transparent
);
String country_code = countryCodeEdit.getText().toString();
String phone = phoneNumberEdit.getText().toString();
String phoneNumber = "+" + country_code + "" + phone;
if (!country_code.isEmpty() || !phone.isEmpty()) {
PhoneAuthOptions options = PhoneAuthOptions.newBuilder(auth)
.setPhoneNumber(phoneNumber)
.setTimeout(60L, TimeUnit.SECONDS)
.setActivity(Login.this)
.setCallbacks(mCallBacks)
.build();
PhoneAuthProvider.verifyPhoneNumber(options);
} else {
processText.setText("Please Enter Country Code and Phone Number");
processText.setTextColor(Color.RED);
processText.setVisibility(View.VISIBLE);
}
}
});
mCallBacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
#Override
public void onVerificationCompleted(#NonNull PhoneAuthCredential phoneAuthCredential) {
signIn(phoneAuthCredential);
}
#Override
public void onVerificationFailed(#NonNull FirebaseException e) {
processText.setText(e.getMessage());
processText.setTextColor(Color.RED);
processText.setVisibility(View.VISIBLE);
}
#Override
public void onCodeSent(#NonNull String s, #NonNull PhoneAuthProvider.ForceResendingToken forceResendingToken) {
super.onCodeSent(s, forceResendingToken);
processText.setText("OTP has been Sent");
processText.setVisibility(View.VISIBLE);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent otpIntent = new Intent(Login.this, otp.class);
otpIntent.putExtra("auth", s);
startActivity(otpIntent);
}
}, 10000);
}
};
}
private void requestCameraPermission() {
//request the camera permission
ActivityCompat.requestPermissions(this, cameraPermissions, CAMERA_REQUEST_CODE);
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
//result of permssion allowed/denied
switch (requestCode) {
case CAMERA_REQUEST_CODE: {
if (grantResults.length > 0) {
//if allowed returns true otherwise false
boolean cameraAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
boolean storageAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
Toast.makeText(this, cameraAccepted + "", Toast.LENGTH_SHORT).show();
}
}
break;
}
}
#Override
public void onBackPressed() {
//dismiss progress dialog
progressDialog.dismiss();
}
#Override
protected void onStart() {
super.onStart();
FirebaseUser user = auth.getCurrentUser();
if (user != null) {
sendToMain();
}
}
private void sendToMain() {
Intent intent = new Intent(Login.this, MainActivity.class);
startActivity(intent);
finish();
}
private void signIn(PhoneAuthCredential credential) {
auth.signInWithCredential(credential).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
sendToMain();
} else {
processText.setText(task.getException().getMessage());
processText.setTextColor(Color.RED);
processText.setVisibility(View.VISIBLE);
}
}
});
}
#Override
public void onDestroy() {
super.onDestroy();
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.cancel();
}
}
}
This is my login activity.
When i write the otp manually , then i don't have this issue, main activity opens only one time but when it auto reads the otp and directly sends me to main activity from login (skipping otp screen) then main activity opens two times.
OTP.java
package com.example.simpleaccounting;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
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;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.auth.PhoneAuthCredential;
import com.google.firebase.auth.PhoneAuthProvider;
public class otp extends AppCompatActivity {
private Button mVerifyCodeBtn;
private EditText otpEdit;
private String OTP;
private FirebaseAuth firebaseAuth;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_otp);
mVerifyCodeBtn = findViewById(R.id.verifycode_btn);
otpEdit = findViewById(R.id.verify_code_edit);
firebaseAuth = FirebaseAuth.getInstance();
OTP = getIntent().getStringExtra("auth");
mVerifyCodeBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String verification_code = otpEdit.getText().toString();
if(!verification_code.isEmpty()){
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(OTP,verification_code);
signIn(credential);
}else{
Toast.makeText(otp.this,"Please Enter OTP",Toast.LENGTH_SHORT).show();
}
}
});
}
private void signIn(PhoneAuthCredential credential){
firebaseAuth.signInWithCredential(credential).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(task.isSuccessful()){
sendToMain();
}else{
Toast.makeText(otp.this,"Verification Failed",Toast.LENGTH_SHORT).show();
}
}
});
}
#Override
protected void onStart() {
super.onStart();
FirebaseUser currentUser = firebaseAuth.getCurrentUser();
if(currentUser!=null){
sendToMain();
}
}
private void sendToMain(){
startActivity(new Intent(otp.this, MainActivity.class));
finish();
}
}
And this is my otp screen activity code.
after login my main activity opens but within 5 seconds my main activity opens again. Can anyone help me out with this issue.
Thanks in advance.
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 am creating app that stores music from device to firebase. I am using Firebase storage, and database, all is working but but when I upload it it shows me progress bar with progress and after that app crashes I found that file is uploaded in storage but not came it database
Getting following error:
2020-07-08 13:57:47.766 32456-32456/xyz.hannanshaikh.firebasemusic E/AndroidRuntime: FATAL EXCEPTION: main
Process: xyz.hannanshaikh.firebasemusic, PID: 32456
java.lang.IllegalStateException: Task is not yet complete
at com.google.android.gms.common.internal.Preconditions.checkState(Unknown Source:29)
at com.google.android.gms.tasks.zzu.zzb(Unknown Source:121)
at com.google.android.gms.tasks.zzu.getResult(Unknown Source:12)
at xyz.hannanshaikh.firebasemusic.MainActivity$3.onSuccess(MainActivity.java:105)
at xyz.hannanshaikh.firebasemusic.MainActivity$3.onSuccess(MainActivity.java:98)
at com.google.firebase.storage.StorageTask.lambda$new$0(com.google.firebase:firebase-storage##19.1.1:123)
at com.google.firebase.storage.StorageTask$$Lambda$1.raise(Unknown Source:6)
at com.google.firebase.storage.TaskListenerImpl.lambda$onInternalStateChanged$2(com.google.firebase:firebase-storage##19.1.1:90)
at com.google.firebase.storage.TaskListenerImpl$$Lambda$3.run(Unknown Source:6)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:201)
at android.app.ActivityThread.main(ActivityThread.java:6823)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)
Here is code:
package xyz.hannanshaikh.firebasemusic;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import android.Manifest;
import android.app.ProgressDialog;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.OpenableColumns;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.OnProgressListener;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;
import com.karumi.dexter.Dexter;
import com.karumi.dexter.PermissionToken;
import com.karumi.dexter.listener.PermissionDeniedResponse;
import com.karumi.dexter.listener.PermissionGrantedResponse;
import com.karumi.dexter.listener.PermissionRequest;
import com.karumi.dexter.listener.single.PermissionListener;
import java.util.Objects;
public class MainActivity extends AppCompatActivity {
private static final String LOG_TAG = "MainActivity";
private boolean checkPermission = false;
Uri uri;
String songName, songUrl;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
if (item.getItemId() == R.id.nav_upload) {
if (validatePermission()) {
pickSongs();
}
}
return super.onOptionsItemSelected(item);
}
private void pickSongs() {
Intent intent_upload = new Intent();
intent_upload.setType("audio/*");
intent_upload.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent_upload, 1);
Log.d(LOG_TAG,"Intent sent for result");
}
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
if (resultCode == RESULT_OK) {
uri = data.getData();
Cursor mCursor = getApplicationContext().getContentResolver()
.query(uri, null, null, null);
int indexedName = Objects.requireNonNull(mCursor).getColumnIndex(OpenableColumns.DISPLAY_NAME);
mCursor.moveToFirst();
songName = mCursor.getString(indexedName);
mCursor.close();
uploadToFirebaseStorage();
}
}
super.onActivityResult(requestCode, resultCode, data);
}
private void uploadToFirebaseStorage() {
Log.d(LOG_TAG,"Method: uploadToFirebaseStorage");
StorageReference storageReference = FirebaseStorage.getInstance().getReference()
.child("Songs").child(Objects.requireNonNull(uri.getLastPathSegment()));
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.show();
storageReference.putFile(uri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Task<Uri> uriTask = taskSnapshot.getStorage().getDownloadUrl();
while (!uriTask.isSuccessful()) {
Uri urlSong = uriTask.getResult();
songUrl = Objects.requireNonNull(urlSong).toString();
uploadDetailsToDatabase();
progressDialog.dismiss();
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
progressDialog.dismiss();
}
}).addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
#Override
public void onProgress(#NonNull UploadTask.TaskSnapshot taskSnapshot) {
double progress = (100.0 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount();
int currentProgress = (int) progress;
progressDialog.setMessage("Uploaded: " + currentProgress + "%");
}
});
}
private void uploadDetailsToDatabase() {
Songs songObj = new Songs(songName, songUrl);
FirebaseDatabase.getInstance().getReference("Songs")
.push().setValue(songObj).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()){
Toast.makeText(MainActivity.this,"Song Uploaded",Toast.LENGTH_SHORT).show();
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(MainActivity.this, e.getMessage(),Toast.LENGTH_SHORT).show();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.custom_menu, menu);
return super.onCreateOptionsMenu(menu);
}
//Validate permission with Dexter library
private boolean validatePermission() {
Dexter.withContext(MainActivity.this)
.withPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
.withListener(new PermissionListener() {
#Override
public void onPermissionGranted(PermissionGrantedResponse permissionGrantedResponse) {
checkPermission = true;
}
#Override
public void onPermissionDenied(PermissionDeniedResponse permissionDeniedResponse) {
checkPermission = false;
}
#Override
public void onPermissionRationaleShouldBeShown(PermissionRequest permissionRequest, PermissionToken permissionToken) {
permissionToken.continuePermissionRequest();
}
}).check();
return checkPermission;
}
}
I think the way you try to upload the song in the database (in Realtime Database I suppose) is wrong. In the method uploadDetailsToDatabase, write:
Declare the reference, in the begining of the class:
DatabaseReference songsDatabase;
Initialize the reference, in onCreate() method, with the path of the song table inside the database:
songsDatabase = FirebaseDatabase.getInstance().getReference("songs");
Add the song object in the realtime database:
Songs songObj = new Songs(songName, songUrl);
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
songsDatabase.child(songName).setValue(songObj).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()){
Toast.makeText(MainActivity.this,"Song Uploaded",Toast.LENGTH_SHORT).show();
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(MainActivity.this, e.getMessage(),Toast.LENGTH_SHORT).show();
}
});
In that way, you create a data(table) in the Realtime Databse, with the name of the song, as the name of this table (songName). Inside this table, you have 2 fields: The song name, and the url of the song.
You may find usefull this answer:
how to resolve java.lang.IllegalStateException: Task is not yet complete Error when uploading image to Firebase storage?
You should avoid using while loop inside a callback listener, instead you can check on the other listener method onComplete() if the upload has been successful or not.
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
Aim
To prompt the data of the current user such as name, address, neighbourhood by acquiring them through the Data Tree within Firebase Database
Picture of the Data Tree
Desrciption
The "London" and "Washington" child within the Data Tree are added in by the Admin account, which means that they are not fixed and that an additional child such as "New York" can be added.
Which would mean that the newly edited Data Tree will have under "Users", there will be "London", "Washington", and "New York"
The other childs, such as those shown below are fixed.
Guards
name
neighbourhood
Police
address
name
neighbourhood
Resident
address
image
name
neighbourhood
position
status
Problem
I receive a "java.lang.NullPointerException" after attempting to prompt the data of the current user who is logged in.
The error is showing at the code String stgUserHomeName = dataSnapshot.child("Users").getValue().toString();.
I was able to acquire my desired data such as "name", "address" and etc. before but when I had a problem when I added in a Not-Fixed parent such as "London" and "Washington".
SettingsActivity Class
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
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.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.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;
import com.squareup.picasso.Callback;
import com.squareup.picasso.NetworkPolicy;
import com.squareup.picasso.Picasso;
import java.io.File;
public class SettingsActivity extends AppCompatActivity {
private DatabaseReference jSettingsDatabase;
private FirebaseUser jFirebaseCurrentUser;
private Toolbar jSettingsToolbar;
private ImageView jSettingsImageView;
private TextView jSettingsDisplayName;
private TextView jSettingsStatus;
private TextView jSettingsAddress;
private TextView jSettingsHomeName;
private Button jSettingsDetailsBtn;
private Button jSettingsImageBtn;
private static final int jSettingsGallerySelect = 1;
private StorageReference jSettingsStorageReference;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
jSettingsStorageReference = FirebaseStorage.getInstance().getReference();
jFirebaseCurrentUser = FirebaseAuth.getInstance().getCurrentUser();
String settingsUserID = jFirebaseCurrentUser.getUid();
jSettingsDatabase = FirebaseDatabase.getInstance().getReference().child("Resident").child(settingsUserID);
jSettingsDatabase.keepSynced(true);
jSettingsImageView = (ImageView) findViewById(R.id.settingUserImg);
jSettingsToolbar = (Toolbar) findViewById(R.id.settingsToolBar);
setSupportActionBar(jSettingsToolbar);
getSupportActionBar().setTitle("Settings");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
jSettingsDisplayName = (TextView) findViewById(R.id.settingUserNameTxt);
jSettingsStatus = (TextView) findViewById(R.id.settingUserStatusTxt);
jSettingsAddress = (TextView) findViewById(R.id.settingUserAddressTxt);
jSettingsHomeName = (TextView) findViewById(R.id.settingsUserHomeTxt);
jSettingsDetailsBtn = (Button) findViewById(R.id.settingChangeDetailsBtn);
jSettingsImageBtn = (Button) findViewById(R.id.settingChangeImageBtn);
jSettingsDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String stgUserHomeName = dataSnapshot.child("Users").getValue().toString();
String stgUserName = dataSnapshot.child("Users").child(stgUserHomeName).child("name").getValue().toString();
String stgUserStatus = dataSnapshot.child("Users").child(stgUserHomeName).child("status").getValue().toString();
String stgUserHomeAddress = dataSnapshot.child("Users").child(stgUserHomeName).child("address").getValue().toString();
final String stgUserImage = dataSnapshot.child("Users").child(stgUserHomeName).child("image").getValue().toString();
jSettingsDisplayName.setText(stgUserName);
jSettingsStatus.setText(stgUserStatus);
jSettingsAddress.setText(stgUserHomeAddress);
if(!stgUserImage.equals("default")){
Picasso.with(SettingsActivity.this).load(stgUserImage).networkPolicy(NetworkPolicy.OFFLINE)
.placeholder(R.drawable.avataricon).into(jSettingsImageView, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
Picasso.with(SettingsActivity.this).load(stgUserImage).placeholder(R.drawable.avataricon).into(jSettingsImageView);
}
});
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
jSettingsDetailsBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String stgUserStatusValue = jSettingsStatus.getText().toString();
String stgUserAddressValue = jSettingsAddress.getText().toString();
String stgUserNameValue = jSettingsDisplayName.getText().toString();
Intent intentDetails = new Intent(SettingsActivity.this, DetailsActivity.class);
intentDetails.putExtra("stgUserNameValue" , stgUserNameValue);
intentDetails.putExtra("stgUserStatusValue", stgUserStatusValue);
intentDetails.putExtra("stgUserAddressValue", stgUserAddressValue);
startActivity(intentDetails);
}
});
jSettingsImageBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intentGallery = new Intent();
intentGallery.setType("image/*");
intentGallery.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intentGallery, "SELECT IMAGE"), jSettingsGallerySelect);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == jSettingsGallerySelect && resultCode == RESULT_OK){
Uri imageUri = data.getData();
String currentUserID = jFirebaseCurrentUser.getUid();
StorageReference imageFilePath = jSettingsStorageReference.child("profileImages").child(currentUserID+".jpg");
imageFilePath.putFile(imageUri).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>(){
#Override
public void onComplete(#NonNull Task<UploadTask.TaskSnapshot> task) {
#SuppressWarnings("VisibleForTests")
String downloadImageUrl = task.getResult().getDownloadUrl().toString();
jSettingsDatabase.child("image").setValue(downloadImageUrl).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
Toast.makeText(SettingsActivity.this, "Upload Successful", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(SettingsActivity.this, "Upload Failed", Toast.LENGTH_SHORT).show();
}
}
});
}
});
}
}
}
Code Explanation
The jSettingsHomeName and stgUserHomeName are meant to be the "London", "Washington", and etc.
Solution to almost Similar Problem
In the link: How to get child of child value from firebase in android? , it shows how a programmer can get the child of a child but the reason as to why I am unable to follow the is because my "London" and "Washington" child tier isn't fixed
Update: Trying Solution given by Ewald B.
jSettingsDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot node : dataSnapshot.getChildren()) {
String stgUserHomeName = node.getKey();
String stgUserName = node.child("Resident").child(settingsUserID).child("name").getValue().toString();
String stgUserStatus = node.child("Resident").child(settingsUserID).child("status").getValue().toString();
String stgUserHomeAddress = node.child("Resident").child(settingsUserID).child("address").getValue().toString();
final String stgUserImage = node.child("Resident").child(settingsUserID).child("image").getValue().toString();
jSettingsHomeName.setText(stgUserHomeName);
jSettingsDisplayName.setText(stgUserName);
jSettingsStatus.setText(stgUserStatus);
jSettingsAddress.setText(stgUserHomeAddress);
if(!stgUserImage.equals("default")){
Picasso.with(SettingsActivity.this).load(stgUserImage).networkPolicy(NetworkPolicy.OFFLINE)
.placeholder(R.drawable.avataricon).into(jSettingsImageView, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
Picasso.with(SettingsActivity.this).load(stgUserImage).placeholder(R.drawable.avataricon).into(jSettingsImageView);
}
});
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Error
java.lang.NullPointerException at com.example.task.app.SettingsActivity$1.onDataChange(SettingsActivity.java:91)
Line 91 points to String stgUserName = node.child("Resident").child(settingsUserID).child("name").getValue().toString();
According to the data model and looking at this statement
jSettingsDatabase = FirebaseDatabase.getInstance().getReference().child("Resident").child(settingsUserID);
there's no node User underneath /Resident/userId. The query needs to start at the database's root which, I assume, is User.
In order to get London, Washington, etc. you need to adapt the code to:
jSettingsDatabase = FirebaseDatabase.getInstance().getReference().child("Users");
...
jSettingsDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot node : dataSnapshot.getChildren()) {
// you will get all cities
String stgUserHomeName = node.getKey();
if(!"Washington".equals(stgUserHomeName)) // or whatever city you need
continue;
// add some more conditional logic to cope with the distinct subtrees that don't have the same properties
// London's Resident has more properties than Washington --> exception is thrown then
// to get the resident's data
node.child("Resident").child(userId).child("address")...
node.child("Resident").child(userId).child("image")...
// or
node.child("Resident").child(userId).getValue(Resident.class);
...
}
....
}
});
There's no user ID in your tree that is needed for this query. But it might be necessary depending on the DB's access rules. Obviously the other queries need to be adapted as well. The city names are also not values but a key (must be unique) so what is important to call DataSnapshot.getKey() method.
In your case the whole database from the User downwards will be fetched and on the client all cities that are not needed will be thrown away. That's a waste of resources.
for testing purposes only set your Firebase Realtime Database rule to allow anyone read and write
eg
{
"rules": {
".write": "true",
".read": "true"
}
}
Check out Firebase Rules documentation
https://firebase.google.com/docs/database/security/
As soon as you have multiple children at the node, it's needed to scan them at the loop. The event indicates that "some" child was changed. Also, try to change the event to onChildAdded. Like below:
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
if (dataSnapshot.getChildrenCount() > 0) {
for (DataSnapshot ds1 : dataSnapshot.getChildren()) {
String stgUserHomeName = ds1.getValue.toString();
.....