【问题标题】:Android Studio - Abort Firebase Firestore document write after time limitAndroid Studio - 在时间限制后中止 Firebase Firestore 文档写入
【发布时间】:2020-09-22 21:22:33
【问题描述】:

我的问题:你能阻止 firebase 文档在特定时间限制后被写入吗?我正在尝试更改用户的密码并在一定时间内通知他们成功或失败。下面是关于我的问题的更多信息(尤其是最后的粗体区域)。

注意:目前,用户的 pin 保存在其本地共享首选项中。但是,同一栋建筑物中可能有几台平板电脑/手机,我希望它们都具有相同的密码。我计划让设备每天检查一次 pin 更新。该 pin 保存在 Shared Preferences 中以供立即使用,而 firestore pin 仅被检查以更新 Shared Preferences pin 号。

要更改他们的 pin,我现在让他们输入他们当前的 pin,然后根据他们的应用程序的共享首选项以及保存在 firestore 文档中的内容进行测试。以下是所有伪代码,但应该足够接近我的观点。

// MAIN ACTIVITY - Global Handler variable
Handler mHandler = new Handler();

...

// Button's OnClick()
if( (pinEntered == sharedPreferencesPin) && (pinEntered == currentFirestorePin)){

    // Connect to firestore and update the new pin
    // OnSuccessListener changes a Singleton boolean value to true or false
    changePin(pinEntered)

    // Show "Please Wait" Loading Class with spinning progress bar widget
    showWaitingScreen();

    // Runnable checks Singleton in 5 seconds to see whether the operation was success or failure
    mHandler(checkSuccessRunnable, 5000);
}

我将我的 firebase 方法分开,所以下一部分是一个不同的类

// Global For PIN UPDATE Class
FirebaseFirestore db = FirebaseFirestore.getInstance();

public void changePin(String pinIn){
    db.collection(pinCollectionPath).document("PIN").set(pinIn)
        .addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void aVoid) {

                // Update singleton - Success
                SingletonClass.setPinChangedBoolean = true;
            }
         })
         .addOnFailureListener(new OnFailureListener() {
             @Override
             public void onFailure(@NonNull Exception e) {

                 // Update singleton - Failed
                 SingletonClass.setPinChangedBoolean = false;
             }
         });
}

回到我的主要活动,我的可运行文件已经完成。 “checkSuccessRunnable”检查单例布尔值。根据值,我创建一个成功或失败警报对话框。

// MAIN ACTIVITY
checkSuccessRunnable= new Runnable() {
    @Override
    public void run() {
            createAlertDialog( SingletonClass.getPinChangedBoolean() );
        }
    }
};

当我尝试在离线状态下更新 firestore pin 文档时出现问题。然后,几分钟后,当平板电脑/手机重新联机时,成功写入文档。我需要在 5 秒内获得失败或成功消息。显然,用户想立即知道他们的 pin 是否已更改。

在测试中,我关闭了 WiFi/数据并尝试更新 Pin 文档。在 5 秒可运行过期后,我收到“更新失败”消息,这是正确的。但是,几分钟后,当我重新打开手机数据时,firestore 文档立即更新。明显的问题是用户在 Runnable 完成后(点击更新按钮 5 秒后)已经收到“失败”消息。

我最初考虑使用广播意图,但应用程序每隔一段时间就会收到设施硬件更改当前活动的请求。即使成功消息稍后呈现给用户,他们也可能永远看不到它。

【问题讨论】:

    标签: android firebase google-cloud-firestore


    【解决方案1】:

    没有直接的解决方案,因为一旦网络可用,Firestore 写入就会自动发送到数据库。

    那么你能做什么?嗯。

    解决方案:

    1.首先检查!:您可以先检查用户是否有活动的网络连接,然后再读取 Firestore。这将要求您检查活动连接(不要只依赖系统的 wifi 和互联网连接)。
    我建议您查看此内容以获取更多详细信息,了解如何完美检查 活动连接Network connection / Internet access

    2。使用交易:如果没有互联网连接,您可以使用交易失败。因此,对于您的用例,如果用户具有活动连接,则将执行事务,如果没有,则事务将失败。最重要的是,它不会自动执行。

    编码愉快!

    【讨论】:

    • 感谢您提供有关交易的信息,这对我来说是新的,我将不得不做一些挖掘工作!根据您的网络点,我跳过在我的帖子中添加它,但我做了一个测试。我基本上向谷歌发送 ping 以确保我可以访问网络,而不仅仅是 wifi 或网络。我测试 MalformedURLException、IOException,并确保返回的响应代码 = HTTP_OK,然后再调用它为好。并不是说我需要所有这些,但我使代码可重用,以防我在另一个项目中需要它。再次感谢。
    • 不建议在任何项目中使用 ping 检查网络连接,因为许多制造商禁用了 ping。您可以参考我在上面回答中给出的链接中的讨论(为您未来的网络项目)。 :-)
    【解决方案2】:

    您尝试做的事情没有简单的解决方法。

    启用persistence 时(Android 上默认启用)写入文档最初存储在持久层中。 SDK 将尝试同步这些写入,直到写入在服务器上实际失败。通常这是超出某些限制或违反安全规则的结果。网络故障会自动静默重试。更改此行为的唯一方法是禁用持久性。如果您这样做,那么您将失去本地缓存在离线行为方面的所有记录优势。

    请注意,如果在后台同步写入时应用进程死亡,则在重新启动应用时同步将自动重新启动。但是,您将不再有用于确定写入是否成功以及何时成功的回调。在这种情况下,您可以查询您写入的数据并查看快照元数据上的hasPendingWrites 标志以确定数据是否已保存。

    如果您需要对所有这些工作方式进行更多控制,您可以随时绕过提供的 SDK 并直接访问 REST API。但是,即使您这样做,也不一定有 100% 的保证结果。网络中断可能会阻止您获得成功写入的结果,而用户永远不会知道。

    您可以选择哪个选项。许多开发人员更愿意让 SDK 执行其默认工作,因为更容易假设写入最终会成功。但是,如果您不喜欢这种假设,则必须自己编写代码。

    【讨论】:

    • 哇,感谢您所做的一切。我认为您为我节省了很大一部分阅读时间,我从中学到了很多东西。我不知道持久性,但正如你所说,最好启用,因为我在 Firestore 中做的比添加用户引脚要多得多 - 我记录了所有通过的事件。老实说,前两段对我来说是黄金。我真的不想深入研究另一个 API,但值得一看。尽管这是很好的信息,但正如@s_o_m_m_y_e_e 所提到的,我将考虑将其作为事务运行。再次感谢!
    猜你喜欢
    • 2020-11-10
    • 2021-10-12
    • 2018-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-14
    • 2021-07-11
    • 1970-01-01
    相关资源
    最近更新 更多