我在使用2个单独的方法时遇到问题,本质上是相同的问题,其中数据库引用正在触发并从相关节点检索所有正确的路径,但是跳过了onDataChange的第一次触发,然后按预期触发,之后给出所需的值。
这两种方法的一般上下文是使用代码/值(指定的路径)在数据库引用中检索值以获取其相关值。该值将被检索并在程序的其他位置使用。
我研究了许多有关onDataChange不触发的问题。解决了我程序中其他地方的许多问题,但是以某种方式,这两种方法仍然存在。我已经多次运行调试,并且不了解调试程序如何显示和获取正确的路径,但是跳过了在onDataChange上的第一次运行,其他实现完全相同原理的方法正在完美运行。
我只发布第一期
在onCreate
databaseReference_AUTH_TABLE = FirebaseDatabase.getInstance().getReference(AUTH_TABLE_TAG); verified = false;
上下文是使用对话框对代码进行身份验证的即时消息。检查代码是否存在于数据库中。如果是的话,其余程序可以运行我需要做的事情
public void authenticateProductID(final String code){
databaseReference_AUTH_TABLE.child(code).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.exists() && !verified){//Exists and is not verified yet
PID = dataSnapshot.getValue().toString();
verified = true;
return;
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
public void showPopupProduct_btn(View view){
final Dialog dialogProductVerification = new Dialog(this);
dialogProductVerification.setContentView(R.layout.layout_popup_product);
Button authenticate = dialogProductVerification.findViewById(R.id.btnPopupProductVerification);
authenticate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EditText verificationCode = dialogProductVerification.findViewById(R.id.editTextPopupCode);
code = verificationCode.getText().toString();
if(noDuplicateCode(code)){
authenticateProductID(code);
if(verified){
getPackage(PID, code);
txtResult.setText(code);
}
else{
Toast.makeText(POSActivity.this, "Authentication Failed", Toast.LENGTH_SHORT).show();
}
}
}
});
dialogProductVerification.show();
}
由于onDataChange不在第一次触发,因此验证为false。但是第二个按钮单击,一切都很完美。
基本上,我的应用程序将在解决后完成。任何帮助都感激不尽。预先谢谢你
答案 0 :(得分:0)
Firebase API是异步的,这意味着onDataChange()
方法在被调用后立即返回,并且它返回的Task中的回调将在一段时间后被调用。无法保证需要多长时间。因此,可能需要几百毫秒到几秒钟的时间才能获得该数据。因为该方法会立即返回,所以尚未从回调中填充您尝试使用的verified
布尔值。因此,简单地将其创建为全局变量完全不能帮助您。
基本上,您正在尝试从异步的API同步使用值。那不是一个好主意。您应该按预期异步处理API。
此问题的快速解决方案是将查询嵌套回调的第一个回调(在onDataChange()方法内部)内的第二个节点的查询代码移动,否则,建议您查看anwser的最后一部分从这个 post 中,我已经解释了如何使用自定义回调来完成。您也可以查看此 video 以获得更好的理解。