【问题标题】:Delete data from Firebase Realtime Database when user closes app用户关闭应用时从 Firebase 实时数据库中删除数据
【发布时间】:2018-05-26 23:24:26
【问题描述】:

我对 Android 开发和 Firebase 非常陌生。

我需要以下帮助:

用户通过 Firebase 密码身份验证(片段称为 SignUp)进行身份验证后,将其保存为实时数据库中的 users->UID->person 的电子邮件。然后,他们将移动到新片段 - AddUsername 片段。这个片段要求一个唯一的用户名。

我想要实现的是,如果用户在未输入用户名的情况下退出并关闭应用程序,则实时数据库中保存的数据将从 Firebase 控制台中删除,并且用户将返回到注册片段以重新启动注册过程。这可以防止创建不活动的电子邮件帐户或错误地“退出”的帐户,并且无法重复使用电子邮件地址。

这是我目前的代码,我不知道我需要什么代码来完成这个。

编辑:我在 AddUsername 片段的 onDestroyView() 上添加了这段代码。当我按下返回按钮时,实时数据库中的数据会被删除,但当我关闭应用程序时,数据不会被删除。

 @Override
public void onDestroyView() {
    super.onDestroyView();


    mAuth.signOut();

    mDatabase.child("users").child(user.getUid()).removeValue();
    Log.i("User: ", "Not saved in database");

    user.delete()
            .addOnCompleteListener(new OnCompleteListener<Void>() {
                @Override
                public void onComplete(@NonNull Task<Void> task) {
                    if (task.isSuccessful()) {
                        Log.d(TAG, "User account deleted.");

                    }


                }



            });

}

提前谢谢你。


public class AddUsername extends Fragment implements View.OnClickListener, TextWatcher {

public AddUsername() {

}


public interface FragmentComm {
    void toSetName();
}

private TextView title, headings, handleError;
private EditText addUsername;
private Button nextButton;
private String getUsername;
private FirebaseAuth mAuth;
private FirebaseUser user;
private DatabaseReference mDatabase;
private FragmentComm fragmentComm;

@Override
public void onAttach(Context context) {
    super.onAttach(context);

    fragmentComm = (FragmentComm) getActivity();
    user = FirebaseAuth.getInstance().getCurrentUser();
    mAuth = FirebaseAuth.getInstance();
    mDatabase = FirebaseDatabase.getInstance().getReference();

}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.add_username, container, false);

    title = view.findViewById(R.id.username_title);
    headings = view.findViewById(R.id.display_user_message);
    handleError = view.findViewById(R.id.message_error);
    addUsername = view.findViewById(R.id.addUsername);
    nextButton = view.findViewById(R.id.nextButton);
    nextButton.setOnClickListener(this);
    addUsername.addTextChangedListener(this);


    return view;
}


@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {

}

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {

}


@Override
public void afterTextChanged(Editable s) {


    getUsername = addUsername.getText().toString();

    if (getUsername.isEmpty()) {

        handleError.setVisibility(View.GONE);
        nextButton.setBackgroundColor(Color.parseColor("#EEEEEE"));
        nextButton.setTextColor(Color.parseColor("#BDBDBD"));
        nextButton.setEnabled(false);


    } else {

        Query query = FirebaseDatabase.getInstance().getReference().child("users").orderByChild("username").equalTo(getUsername);
        query.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                if (dataSnapshot.exists()) {

                    handleError.setText(R.string.username_not_available);
                    handleError.setVisibility(View.VISIBLE);
                    handleError.setTextColor(Color.parseColor("#F50057"));
                    nextButton.setBackgroundColor(Color.parseColor("#EEEEEE"));
                    nextButton.setTextColor(Color.parseColor("#BDBDBD"));
                    nextButton.setEnabled(false);

                } else {

                    handleError.setText(R.string.username_available);
                    handleError.setVisibility(View.VISIBLE);
                    handleError.setTextColor(Color.parseColor("#26C485"));
                    nextButton.setBackgroundColor(Color.parseColor("#0277BD"));
                    nextButton.setTextColor(Color.parseColor("#FFFFFF"));
                    nextButton.setEnabled(true);

                }
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                Log.i("Give info", "Error");


            }
        });

    }

}


@Override
public void onClick(View v) {

    switch (v.getId()) {

        case R.id.nextButton:

            checkUsernameAlreadyExist();

    }


}

private void checkUsernameAlreadyExist() {

    getUsername = addUsername.getText().toString();


    Query query = FirebaseDatabase.getInstance().getReference().child("users").orderByChild("username").equalTo(getUsername);
    query.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            if (dataSnapshot.exists()) {

                handleError.setText(R.string.username_not_available);
                handleError.setVisibility(View.VISIBLE);
                handleError.setTextColor(Color.parseColor("#F50057"));


            } else {

                handleError.setText(R.string.username_available);
                handleError.setVisibility(View.VISIBLE);
                handleError.setTextColor(Color.parseColor("#26C485"));

               fragmentComm.toSetName();
                setDatabaseName();

            }
        }


        @Override
        public void onCancelled(DatabaseError databaseError) {
            Log.i("Give info", "Error");


        }
    });

}


private void setDatabaseName() {

    mDatabase.child("users").child(user.getUid()).child("username").setValue(getUsername);


}

【问题讨论】:

    标签: android firebase firebase-realtime-database


    【解决方案1】:

    我认为这对于onDisconnect 处理程序来说可能是一个很好的用例。这些是应用程序在连接时发送到 Firebase 数据库的写入指令,数据库服务器会在检测到客户端消失后执行这些指令。

    一个例子:

    private void setDatabaseName() {
      DatabaseReference usernameRef = mDatabase.child("users").child(user.getUid()).child("username");
      usernameRef.setValue(getUsername);
      usernameRef.onDisconnection().removeValue();
    }
    

    有关更多信息,请参阅Firebase documentation on onDisconnect handlers

    但这仅适用于数据库。您可能还需要寻找其他方法来清理 Firebase 身份验证帐户。

    另请注意,您为确保用户名唯一而采取的方法效率不高。有关更惯用的方法,请参阅:

    【讨论】:

    • 谢谢弗兰克。 onDisconnect 通过在片段的 onStop 生命周期中调用它来工作。是的,我现在正在寻找身份验证部分的修复程序。感谢您提供有关独特用户名的反馈,非常有用的资源。
    【解决方案2】:

    我相信您需要在活动本身的onStop()onDestroy() 中添加用于删除它的相同代码,并用 if 条件检查用户是否输入用户名

    但是请记住,如果应用程序是 onPause(),它可能会绕过 onDestroy()onStop() 方法关闭,因此您可能还需要在 onPause() 中添加代码,然后在恢复时用户需要从头开始

    【讨论】:

    • 感谢您对 PeeGee 的建议。是的,这也是我最初的快速修复解决方案。 Activity 本身的 if 条件,用于在用户退出/最小化或 X/关闭应用程序时检查用户名是否已输入或为空。如果为空,则删除数据。当我回头看时,这并不能提供良好的用户体验。用户可以在不输入用户名的情况下最小化应用程序(调用 onPause),但用户不需要从头开始。仅在应用实际关闭时重新开始。
    • 当然@KasianBlitheCaballero!是的,您完全正确,但这就是我能达到的程度,但提供的另一个答案是更好的解决方案,脱帽致敬!祝你好运队友:)
    • 此解决方案可能无法有效触发。 onDisconnect 由 Firebase 触发,因为 Firebase 会监控连接。
    猜你喜欢
    • 2020-01-17
    • 2021-06-04
    • 1970-01-01
    • 2019-04-18
    • 2020-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多