删除Firebase数据库的值后,应用程序崩溃 [英] App crash after remove value of Firebase Database

查看:60
本文介绍了删除Firebase数据库的值后,应用程序崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试删除firebase数据库的值时遇到问题,它可以正常工作,但我的应用仍然崩溃:/

I have a problem when I try removing values of firebase database, It's works correctly but my app still crashing :/

所以我设法使代码起作用,该代码为"Carte"添加了一个值.

So I managed to get the code to work which adds a value to "Carte".

但是现在我正在尝试使用NumberPicker删除一定数量的Carte并将条目添加到其他条目中.

But now I'm trying with a NumberPicker to remove a certain number of Carte and add entries to something else.

这是我的代码,该代码添加带有循环的条目.

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();


    }

它可以正常工作.但是当我添加代码以从Carte race_fragment代码中删除值时

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

并且日志在另一个片段中指示错误:/

这是整个logCat错误:

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

帐户片段代码

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);

    }

}

}

****

但是我不明白的是,当我删除此代码时:

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) {}
                        });

应用程序不再崩溃.但是我需要这个代码x)

The application no longer crashes. But I need this code x)

先谢谢了.

推荐答案

您要在片段的onCreateView中附加一个永久侦听器.由于您从未删除过监听程序,因此只要您的应用程序运行,它就会一直观察数据库中的数据.因此,当片段不再(或尚未)附加到视图时,其onDataChange可能会被调用.

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.

由于这个原因,当片段与活动分离时,您应该小心删除监听器.我建议在onStart()中附加侦听器,然后在onStop中将其删除,但是由于您在onCreateView中附加了它,因此也可以在onDestroyView中将其删除.

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.

这需要执行以下步骤:

  1. 在片段中添加一个字段以跟踪侦听器:

  1. Add a field in your fragment to track the listener:

ValueEventListener mFirebaseListener

  • 在附加onCreateViewonStart时将其设置为侦听器字段:

  • 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);
    

  • 删除onDestroyViewonStop中的侦听器:

  • Remove the listener in onDestroyView or onStop:

    FirebaseDatabase.getInstance().getReference().child("users").child(user.getUid()).removeEventListener(mFirebaseListener);
    

  • 请参阅:

    • Why getContext() in fragment sometimes returns null?
    • the Android documentation on the lifecycle of a fragment

    这篇关于删除Firebase数据库的值后,应用程序崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆