Android 来自firebase的函数addListenerForSingleValueEvent

Android 来自firebase的函数addListenerForSingleValueEvent,android,firebase,firebase-realtime-database,Android,Firebase,Firebase Realtime Database,使用Firebase数据库。 我有一个数据库,用于存储患者的注册信息。 注册新患者时,我会检查该患者是否已经注册 下面的功能检查此人是否已注册。 我通过“用户/电话号码/患者姓名”来检查这一点。 如果DataSnapshot不为null,则已存在注册 private boolean checkAlreadyRegistered(){ final boolean[] alreadyRegistered = {false}; /*Get the reference*/ mD

使用Firebase数据库。 我有一个数据库,用于存储患者的注册信息。 注册新患者时,我会检查该患者是否已经注册

下面的功能检查此人是否已注册。 我通过“用户/电话号码/患者姓名”来检查这一点。 如果DataSnapshot不为null,则已存在注册

private boolean checkAlreadyRegistered(){

    final boolean[] alreadyRegistered = {false};
    /*Get the reference*/
    mDatabaseReference = FirebaseDatabase.getInstance().getReference("Users/" + childDetails.getPhone() + "/" + childDetails.getPatientName());
    mDatabaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            Log.d(TAG, "onDataChange: " + dataSnapshot);
            if (dataSnapshot.getValue() != null) {

                AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
                builder.setTitle("Record Already Exists");
                builder.setMessage("The current patient is already registered");
                builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {

                        alreadyRegistered[0] = true;
                    }
                });
                builder.create();
                builder.show();
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

            Toast.makeText(getContext(), "Some error occured", Toast.LENGTH_LONG).show();
        }
    });
    return  alreadyRegistered[0];
}
从saveInDatabase调用上述函数

void saveInDatabase(Long patient_id) {


    boolean alreadyRegistered = checkAlreadyRegistered();
    if (alreadyRegistered) {
        resetRegisterFields();
        return;
    }
    mDatabaseReference = FirebaseDatabase.getInstance().getReference("Current_registered_users");
    mDatabaseReference.setValue(patient_id + 1);
    childDetails.setPatient_id(patient_id);
    mDatabaseReference = FirebaseDatabase.getInstance().getReference("Users");
    Log.d(TAG, "saveInDatabase: "+mDatabaseReference);
    mDatabaseReference.child(childDetails.getPhone()).child(childDetails.getPatientName()).child("Registration Details").setValue(childDetails);
    Button bt = (Button) getView().findViewById(R.id.buttonRegister);
    resetRegisterFields();
    progressDialog.dismiss();
    displayPid(patient_id);
    bt.setEnabled(true);
    .
    .
}
我想做的事情-检查是否已经根据电话号码/患者姓名进行了登记,如果没有,请保存详细信息

问题-进行新注册时,会将其添加到数据库中,但之后会显示checkAlreadyRegistered()->onDataChange中的消息“.已注册”


为什么会出现此消息,以及如何解决此问题?

Firebase中的所有数据读取都是异步进行的,因此我建议您将代码更改为如下所示:

private void checkAlreadyRegistered(){

    /*Get the reference*/
    mDatabaseReference = FirebaseDatabase.getInstance().getReference("Users/" + childDetails.getPhone() + "/" + childDetails.getPatientName());
    mDatabaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            Log.d(TAG, "onDataChange: " + dataSnapshot);
            if (dataSnapshot.getValue() != null) {

                AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
                builder.setTitle("Record Already Exists");
                builder.setMessage("The current patient is already registered");
                builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                        resetRegisterFields();
                    }
                });
                builder.create();
                builder.show();
            }
            else
            {
                saveInDatabase(patient_id); //TODO change this accordingly
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

            Toast.makeText(getContext(), "Some error occured", Toast.LENGTH_LONG).show();
        }
    });
}
以及您的保存方法:

void saveInDatabase(Long patient_id) {
    mDatabaseReference = FirebaseDatabase.getInstance().getReference("Current_registered_users");
    mDatabaseReference.setValue(patient_id + 1);
    childDetails.setPatient_id(patient_id);
    mDatabaseReference = FirebaseDatabase.getInstance().getReference("Users");
    Log.d(TAG, "saveInDatabase: "+mDatabaseReference);
    mDatabaseReference.child(childDetails.getPhone()).child(childDetails.getPatientName()).child("Registration Details").setValue(childDetails);
    Button bt = (Button) getView().findViewById(R.id.buttonRegister);
    resetRegisterFields();
    progressDialog.dismiss();
    displayPid(patient_id);
    bt.setEnabled(true);
    .
    .
}

您必须等待Firebase的响应。您可以添加一个回调,以便在检索完代码后运行其余的代码。这样做:

private void checkAlreadyRegistered(){

    /*Get the reference*/
    mDatabaseReference = FirebaseDatabase.getInstance().getReference("Users/" + childDetails.getPhone() + "/" + childDetails.getPatientName());
    mDatabaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            Log.d(TAG, "onDataChange: " + dataSnapshot);
            if (dataSnapshot.getValue() != null) {

                AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
                builder.setTitle("Record Already Exists");
                builder.setMessage("The current patient is already registered");
                builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                        resetRegisterFields();
                    }
                });
                builder.create();
                builder.show();
            }
            else
            {
                saveInDatabase(patient_id); //TODO change this accordingly
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

            Toast.makeText(getContext(), "Some error occured", Toast.LENGTH_LONG).show();
        }
    });
}
创建一个名为
ServerCallback
的接口:

public interface ServerCallback
{
    void onSuccess(boolean result);
}
在您的
checkAlreadyRegistered()
方法中,添加回调,以便在从Firebase检索数据后运行回调:

private void checkAlreadyRegistered(final ServerCallback callback){
    final boolean[] alreadyRegistered = {false};
    /*Get the reference*/
    mDatabaseReference = FirebaseDatabase.getInstance().getReference("Users/" + childDetails.getPhone() + "/" + childDetails.getPatientName());
    mDatabaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            Log.d(TAG, "onDataChange: " + dataSnapshot);
            if (dataSnapshot.getValue() != null) {
                AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
                builder.setTitle("Record Already Exists");
                builder.setMessage("The current patient is already registered");
                builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {

                        alreadyRegistered[0] = true;
                        callback.onSuccess(alreadyRegistered[0]);
                    }
                });
                builder.create();
                builder.show();
            }
            else
               callback.onSuccess(alreadyRegistered[0]);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            Toast.makeText(getContext(), "Some error occured", Toast.LENGTH_LONG).show();
        }
    });
}
然后在
saveInDatabase()
中,等待回调,然后运行其余代码:

void saveInDatabase(Long patient_id) {
    boolean alreadyRegistered = checkAlreadyRegistered(new ServerCallback() {
        @Override
        public void onSuccess(boolean result)
        {
            if (alreadyRegistered) {
                resetRegisterFields();
                return;
            }
            mDatabaseReference = FirebaseDatabase.getInstance().getReference("Current_registered_users");
            mDatabaseReference.setValue(patient_id + 1);
            childDetails.setPatient_id(patient_id);
            mDatabaseReference = FirebaseDatabase.getInstance().getReference("Users");
            Log.d(TAG, "saveInDatabase: "+mDatabaseReference);
            mDatabaseReference.child(childDetails.getPhone()).child(childDetails.getPatientName()).child("Registration Details").setValue(childDetails);
            Button bt = (Button) getView().findViewById(R.id.buttonRegister);
            resetRegisterFields();
            progressDialog.dismiss();
            displayPid(patient_id);
            bt.setEnabled(true);
            .
            .
        });
 }
onDataChange()
异步激发<代码>checkAlreadyRegistered()在结果可用之前返回。有关详细说明,请参见此答案:因此,从onDataChange()调用saveInDatabase()将解决问题,对吗?