I have a problem when I try removing values of firebase database, It's works correctly but my app still crashing:/
So I managed to get the code to work which adds a value to "Carte".
But now I'm trying with a NumberPicker to remove a certain number of Carte and add entries to something else.
Here is my code which adds entries with a loop.
if (i == R.id.ParticipCarte1) {
FirebaseUser user = mAuth.getCurrentUser();
final NumberPicker np = new NumberPicker(getActivity());
np.setMinValue(1);
FirebaseDatabase.getInstance().getReference().child("users").child(user.getUid()).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
Integer nbrcarte = dataSnapshot.child("carte").getValue(Integer.class);
if (dataSnapshot.exists()) {
np.setMaxValue(nbrcarte);
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
final AlertDialog.Builder builder1 = new AlertDialog.Builder(getContext());
builder1.setView(np);
builder1.setMessage(R.string.add_particip_msg);
builder1.setCancelable(true);
builder1.setPositiveButton(
R.string.confirme_particip,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
final int nbrFois = np.getValue();
mAuth = FirebaseAuth.getInstance();
FirebaseUser user = mAuth.getCurrentUser();
int a = 0;
while (a < nbrFois) {
writeNewUser1(user.getEmail());
a++;
}
}
});
builder1.setNegativeButton(
R.string.reset_pass_no_btn,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert11 = builder1.create();
alert11.show();
}
It works without problems. but when I add the code to remove values from Carte contest_fragment code
if (i == R.id.ParticipCarte1) {
FirebaseUser user = mAuth.getCurrentUser();
final NumberPicker np = new NumberPicker(getActivity());
np.setMinValue(1);
FirebaseDatabase.getInstance().getReference().child("users").child(user.getUid()).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
Integer nbrcarte = dataSnapshot.child("carte").getValue(Integer.class);
if (dataSnapshot.exists()) {
np.setMaxValue(nbrcarte);
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
final AlertDialog.Builder builder1 = new AlertDialog.Builder(getContext());
builder1.setView(np);
builder1.setMessage(R.string.add_particip_msg);
builder1.setCancelable(true);
builder1.setPositiveButton(
R.string.confirme_particip,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
final int nbrFois = np.getValue();
mAuth = FirebaseAuth.getInstance();
FirebaseUser user = mAuth.getCurrentUser();
mDatabase.child("users").child(user.getUid()).child("carte").runTransaction(new Transaction.Handler() {
@Override
public Transaction.Result doTransaction(MutableData mutableData) {
Integer carte = mutableData.getValue(Integer.class);
mutableData.setValue(carte - nbrFois);
return Transaction.success(mutableData);
}
@Override
public void onComplete(DatabaseError databaseError, boolean b, DataSnapshot dataSnapshot) {}
});
int a = 0;
while (a < nbrFois) {
writeNewUser1(user.getEmail());
a++;
}
}
});
builder1.setNegativeButton(
R.string.reset_pass_no_btn,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert11 = builder1.create();
alert11.show();
}
It works fine in the database but the application crashes
And the logs indicate an error in another fragment:/
This is the entire logCat error:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.victorapp.winid, PID: 9923
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getString(int)' on a null object reference
at com.victorapp.winid.Account_fragment$1.onDataChange(Account_fragment.java:85)
at com.google.firebase.database.core.ValueEventRegistration.fireEvent(com.google.firebase:firebase-database@@19.2.1:75)
at com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database@@19.2.1:63)
at com.google.firebase.database.core.view.EventRaiser$1.run(com.google.firebase:firebase-database@@19.2.1:55)
at android.os.Handler.handleCallback(Handler.java:907)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:216)
at android.app.ActivityThread.main(ActivityThread.java:7506)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.Zygote
Account Fragment code
public class Account_fragment extends Fragment implements View.OnClickListener {
FirebaseAuth auth;
FirebaseUser user;
TextView profileTxt;
DatabaseReference reference;
DatabaseReference DeleteRef;
Button NbrCarte;
private FirebaseAuth mAuth;
public Account_fragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_account_fragment, container, false);
auth = FirebaseAuth.getInstance();
profileTxt = rootView.findViewById(R.id.BonjourText);
user = auth.getCurrentUser();
NbrCarte = rootView.findViewById(R.id.btnCartes);
rootView.findViewById(R.id.BtnDisconnect).setOnClickListener(this);
rootView.findViewById(R.id.btnDelete).setOnClickListener(this);
rootView.findViewById(R.id.btnPass).setOnClickListener(this);
rootView.findViewById(R.id.btnCartes).setOnClickListener(this);
mAuth = FirebaseAuth.getInstance();
reference = FirebaseDatabase.getInstance().getReference().child("users").child(user.getUid());
reference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
String username = dataSnapshot.child("username").getValue().toString();
profileTxt.setText(getContext().getString(R.string.welcome_user) + username);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
mAuth = FirebaseAuth.getInstance();
FirebaseUser user = mAuth.getCurrentUser();
FirebaseDatabase.getInstance().getReference().child("users").child(user.getUid()).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
String nbrcarte = dataSnapshot.child("carte").getValue().toString();
NbrCarte.setText(nbrcarte + getString(R.string.cartes_title));
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
return rootView;
}
private void signOut() {
mAuth.signOut();
Intent SignOutIntent = new Intent(getActivity(), MainActivity.class);
Account_fragment.this.startActivity(SignOutIntent);
}
private String email = "";
private void lostPassword (){
final EditText input = new EditText(getActivity());
input.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
final AlertDialog.Builder builderLost = new AlertDialog.Builder(getContext());
builderLost.setTitle(R.string.reset_password);
builderLost.setMessage(R.string.type_email);
builderLost.setView(input);
builderLost.setCancelable(true);
builderLost.setPositiveButton(
R.string.reset_pass_ok_btn,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id){
email = input.getText().toString();
auth.sendPasswordResetEmail(email)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "Email sent.");
Toast.makeText(getActivity(),
getActivity().getText(R.string.email_send) + email,
Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getActivity(),
getActivity().getText(R.string.email_err) + email,
Toast.LENGTH_LONG).show();
}
}
});
}
});
builderLost.setNegativeButton(
R.string.reset_pass_no_btn,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert11 = builderLost.create();
alert11.show();
}
public void onClick(View v) {
int i = v.getId();
if (i == R.id.BtnDisconnect) {
signOut();
}
if (i == R.id.btnDelete){
final AlertDialog.Builder builderSuppr = new AlertDialog.Builder(getContext());
builderSuppr.setMessage(R.string.delete_alert_msg);
builderSuppr.setCancelable(true);
builderSuppr.setPositiveButton(
R.string.reset_pass_ok_btn,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id){
user.delete()
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Log.d(TAG, "Compte supprimer.");
DeleteRef = FirebaseDatabase.getInstance().getReference()
.child("users").child(user.getUid());
DeleteRef.removeValue();
signOut();
}
}
});
}
});
builderSuppr.setNegativeButton(
R.string.reset_pass_no_btn,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert11 = builderSuppr.create();
alert11.show();
}
if (i == R.id.btnPass){
lostPassword();
}
if (i == R.id.btnCartes){
Intent CartesIntent = new Intent(getActivity(), referralActivity.class);
Account_fragment.this.startActivity(CartesIntent);
}
}
}
**EDIT: **
but what I can't understand is that when I remove this code:
mDatabase.child("users").child(user.getUid()).child("carte").runTransaction(new Transaction.Handler() {
@Override
public Transaction.Result doTransaction(MutableData mutableData) {
Integer carte = mutableData.getValue(Integer.class);
mutableData.setValue(carte - nbrFois);
return Transaction.success(mutableData);
}
@Override
public void onComplete(DatabaseError databaseError, boolean b, DataSnapshot dataSnapshot) {}
});
The application no longer crashes. But I need this code x)
Thank's in advance.
You're attaching a permanent listener in the onCreateView
of your fragment. Since you never remove the listener, it keeps observing the data in the database as long as your app runs. Because of this, its onDataChange
may get called when the fragment is no longer (or not yet) attached to the view.
For this reason you should take care to remove the listener when the fragment is detached from the activity. I'd recommend attaching the listener in onStart()
and then removing it in onStop
, but since you attach it in onCreateView
you can also remove it in onDestroyView
.
This requite the following steps:
Add a field in your fragment to track the listener:
ValueEventListener mFirebaseListener
Set the listener field in the onCreateView
or onStart
when you attach it:
mFirebaseListener = new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) { Integer nbrcarte = dataSnapshot.child("carte").getValue(Integer.class); if (dataSnapshot.exists()) { np.setMaxValue(nbrcarte); } } @Override public void onCancelled(@NonNull DatabaseError databaseError) { throw databaseError.toException(); // never ignore errors } }); FirebaseDatabase.getInstance().getReference().child("users").child(user.getUid()).addValueEventListener(mFirebaseListener);
Remove the listener in onDestroyView
or onStop
:
FirebaseDatabase.getInstance().getReference().child("users").child(user.getUid()).removeEventListener(mFirebaseListener);
See:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.