我正在编写一个Android应用,目前正在尝试从Firebase数据库读取数据。我按照文档here进行阅读。现在,在调用OnCancelled(表示Firebase读取失败)的情况下,我检查失败是否是由于内部连接引起的,因此我可以提示用户进行处理。
所以现在我的代码包含以下内容:
该类中的静态函数会检查互联网,向用户显示一个对话框,尝试每两秒钟重新连接一次,如果未连接,则再次显示该对话框。它会一直这样做,直到连接了Internet,然后它会在Internet连接后回调一个回调函数以执行操作。
具有ValueEventListener
和onDataChange
的firebase onCancelled
这两个代码:
连接
/**
* Defined in some separate file in a class called SharedStuff
* This function launches a child thread for checking internet connection.
* It also shows a dialog for the user to reconnect
* Body of the function is irrelevant
*
* @param caller The caller activity. Needed to launch dialogs
* @param callback Actions to do when internet connects
* @param timeout A timeout period after which we will stop trying
*/
public static void isInternetAvailable(final Activity caller, final Callable<Void> callback, final int timeout);
火力基地
/**
* Firebase stuff
* Inside my main activity file
*/
mAuth = FirebaseAuth.getInstance();
mDB = FirebaseDatabase.getInstance();
mDB.getReference("users").child(mAuth.getCurrentUser().getUid()).addValueEventListener(new ValueEventListener()
{
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot)
{
// Do stuff
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError)
{
if (databaseError.getCode() == DatabaseError.DISCONNECTED || databaseError.getCode() == DatabaseError.NETWORK_ERROR)
{
/**
* Need to try call the internet connection function here with some callback!
*/
SharedStuff.isInternetAvailable(MainActivity.this, new Callable<Void>()
{
@Override
public Void call()
{
// Need to fill this callback!
return null;
}
}, 2000);
}
else
{
Log.wtf(TAG, "Reading database failed", databaseError.toException());
}
}
});
因此,现在我被困在尝试用适当的操作填充此回调。基本上我想做的是尝试再次阅读直到阅读成功,或者如果由于相同原因失败则再次显示相同的Internet对话框(我知道很难做到这一点,但是我确实看到了一些网络连接闪烁,并希望通过处理这种情况来保持安全)。
因此,我考虑/尝试过的方法如下:
1-强制发生数据更改事件
但是,我在firebase文档中找不到会产生这种效果的任何API调用。
2-再次手动添加
ValueEventListener
在这种情况下,我使用
addListenerForSingleValueEvent
而不是addValueEventListener
,但随后尝试在onCancelled内再次连接它!这种情况的代码如下所示:
/**
* Firebase stuff
*/
mAuth = FirebaseAuth.getInstance();
mDB = FirebaseDatabase.getInstance();
mDB.getReference("users").child(mAuth.getCurrentUser().getUid()).addListenerForSingleValueEvent(new ValueEventListener()
{
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot)
{
// Do stuff
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError)
{
if (databaseError.getCode() == DatabaseError.DISCONNECTED || databaseError.getCode() == DatabaseError.NETWORK_ERROR)
{
/**
* Need to call the internet connection function here with some callback!
*/
SharedStuff.isInternetAvailable(WelcomeActivity.this, new Callable<Void>()
{
@Override
public Void call()
{
mDB.getReference("users").child(mAuth.getCurrentUser().getUid()).addListenerForSingleValueEvent(Outer.this);
return null;
}
}, 2000);
}
else
{
Log.wtf(TAG, "Reading database failed", databaseError.toException());
}
}
});
在这种情况下的问题是关键字
this
是针对Callable
对象的,而不是针对ValueEventListener
的,并且我不确定用什么替换单词Outer
来使this
指向侦听器代替!我在这里可以做什么以重新连接并重新阅读?无论是选项1或2,还是其他所有选项。我只是想在调用
onCancelled
时执行以下操作:检查Internet连接,连接后重试读取,如果连接再次失败,则继续执行此操作(您可以将其视为递归)! 最佳答案
onCancelled被触发:
...如果此侦听器在服务器上失败或
由于安全性和Firebase数据库规则而被删除。
如果出现网络错误,则不会调用它。当客户端无法访问Firebase服务器时,它将在内部重试连接以及所有未决的读取或写入。您无需编写任何代码即可处理这种情况。实际上,您无法更改此行为。