我正在编写一个Android应用,目前正在尝试从Firebase数据库读取数据。我按照文档here进行阅读。现在,在调用OnCancelled(表示Firebase读取失败)的情况下,我检查失败是否是由于内部连接引起的,因此我可以提示用户进行处理。

所以现在我的代码包含以下内容:


该类中的静态函数会检查互联网,向用户显示一个对话框,尝试每两秒钟重新连接一次,如果未连接,则再次显示该对话框。它会一直这样做,直到连接了Internet,然后它会在Internet连接后回调一个回调函数以执行操作。
具有ValueEventListeneronDataChange的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服务器时,它将在内部重试连接以及所有未决的读取或写入。您无需编写任何代码即可处理这种情况。实际上,您无法更改此行为。

09-11 19:17
查看更多