提问者:小点点

移除 Firebase 数据库的值后应用崩溃


当我尝试删除Firebase数据库的值时,我遇到了一个问题,它工作正常,但我的应用程序仍然崩溃:/

所以我设法让代码工作,这增加了“照单全收”的价值。

但现在我正尝试用一个数字选择器来删除一定数量的Carte,并添加条目到其他东西中。

这是我的代码,它使用循环添加条目。

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


    }

它在数据库中工作正常,但应用程序崩溃

日志指示另一个片段中的错误:/

这是整个日志猫错误:

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

    }

}

}

**编辑:**

但我无法理解的是,当我删除此代码时:

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)

提前谢谢。


共1个答案

匿名用户

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

因此,当片段从活动中分离出来时,您应该小心地移除侦听器。我建议在< code>onStart()中附加侦听器,然后在< code>onStop中移除它,但是因为您在< code>onCreateView中附加了它,所以您也可以在< code>onDestroyView中移除它。

这将重复以下步骤:

>

  • 在片段中添加一个字段来跟踪侦听器:

    ValueEventListener mFirebaseListener
    

    附加侦听器时,在< code>onCreateView或< code>onStart中设置侦听器字段:

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

    删除onDestroyViewon Stop中的侦听器:

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

    参见:

      < li >为什么fragment中的getContext()有时会返回null? < li >关于片段生命周期的Android文档