简体   繁体   English

Android Studio - 中止 Firebase Firestore 文档在时间限制后写入

[英]Android Studio - Abort Firebase Firestore document write after time limit

My Question: Can you stop a firebase document from being written after a certain time limit?我的问题:你能阻止 firebase 文件在一定时间限制后被写入吗? I am attempting to change a user's pin and notify them of success or failure within a time limit.我正在尝试更改用户的密码并在时限内通知他们成功或失败。 More on my issue below (especially the bold area at the end).下面是关于我的问题的更多信息(尤其是末尾的粗体区域)。

Note: Currently, a user's pin is saved in their local shared preferences.注意:目前,用户的 pin 保存在他们的本地共享首选项中。 However, there may be a few tablets/phones in the same building and I want them to all have the same pin number.但是,同一建筑物中可能有几台平板电脑/手机,我希望它们都具有相同的密码。 I plan to have the devices check for pin updates once per day.我计划让设备每天检查一次 pin 更新。 The pin is saved in Shared Preferences for immediate usage, whereas the firestore pin is only checked to update the Shared Preferences pin number.该 pin 保存在共享首选项中以供立即使用,而仅检查 firestore pin 以更新共享首选项 pin 编号。

To change their pin, I now have them enter their current pin, then test this against their app's shared preferences as well as what is saved in the firestore document.要更改他们的 pin,我现在让他们输入他们当前的 pin,然后根据他们应用程序的共享首选项以及保存在 firestore 文档中的内容对其进行测试。 Below is all psudocode, but should be close enough to get my point across.以下是所有伪代码,但应该足够接近以表达我的观点。

// 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);
}

I keep my firebase methods separate, so the next section here is a different class我将 firebase 方法分开,所以这里的下一部分是不同的 class

// 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;
             }
         });
}

Back to my Main activity I have my runnable complete.回到我的主要活动,我的可运行程序已经完成。 The "checkSuccessRunnable," checks the Singleton boolean value. “checkSuccessRunnable”检查 Singleton boolean 值。 Depending on the value, I create a success or failure Alert Dialog.根据值,我创建了一个成功或失败的警报对话框。

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

My issue arises when I try to update the firestore pin document while offline.当我尝试在离线时更新 firestore pin 文档时,我的问题就出现了。 Then, minutes later, successfully writing the document when the Tablet/Phone comes back online.然后,几分钟后,当平板电脑/手机重新上线时,成功写入文档。 I need to either have a failure or success message within 5 seconds.我需要在 5 秒内收到失败或成功消息。 Obviously, the user wants to know if their pin was changed, or not, immediately.显然,用户想立即知道他们的密码是否已更改。

In testing, I turned my WiFi/Data off and tried to update the Pin document.在测试中,我关闭了 WiFi/Data 并尝试更新 Pin 文档。 After the 5 second runnable expired, I get a "Failed to update" message, which is correct.在 5 秒可运行程序到期后,我收到一条“更新失败”消息,这是正确的。 However, after a few minutes, when I turned my phone data back on, the firestore document was immediately updated.然而,几分钟后,当我重新打开手机数据时,firestore 文件立即更新了。 The obvious problem is that the user already received a "failure" message after the Runnable completed (5 seconds after clicking the update button).明显的问题是用户在 Runnable 完成后(点击更新按钮 5 秒后)已经收到“失败”消息。

I originally thought about using a broadcast intent , but the app receives requests to change the current activity, by the facility hardware, every so often.我最初考虑使用 broadcast intent ,但应用程序经常收到设施硬件更改当前活动的请求。 Even if the success message is presented to the user later, they may never see it.即使稍后将成功消息呈现给用户,他们也可能永远看不到它。

What you're trying to do has no simple workaround.您正在尝试做的事情没有简单的解决方法。

When persistence is enabled (default is enabled on Android) writes to documents are initially stored in the persistence layer.启用持久性(Android 上默认启用)时,对文档的写入最初存储在持久层中。 The SDK will attempt to synchronize those writes until the write actually fails on the server. SDK 将尝试同步这些写入,直到写入在服务器上实际失败。 Typically this is a result of exceeding some limit or violating a security rule.通常,这是超出某些限制或违反安全规则的结果。 Network failure are automatically retried silently.网络故障会自动静默重试。 The only way to change this behavior is to disable persistence.更改此行为的唯一方法是禁用持久性。 If you do that, then you will lose all of the documented benefits of the local cache with respect to its offline behavior.如果你这样做,那么你将失去本地缓存在其离线行为方面的所有记录的好处。

Note that if the app process dies while a write is being synchronized in the background, the synchronization will restart automatically when the app is restarted.请注意,如果应用程序进程在后台同步写入时挂掉,则同步将在应用程序重新启动时自动重新启动。 However, you will no longer have a callback to use to determine if and when the write succeeded.但是,您将不再有回调可用于确定写入是否成功以及何时成功。 In that case, you can query for the data you wrote and look at the hasPendingWrites flag on the snapshot metadata to determine if the data is saved.在这种情况下,您可以查询您写入的数据并查看快照元数据上的hasPendingWrites标志以确定数据是否已保存。

If you require more control over how all this works, you can always bypass the provided SDK and go straight to the REST API .如果您需要更多地控制这一切的工作方式,您总是可以绕过提供的 SDK 和 go 直接到REST API However, even if you do this, you don't necessarily have a 100% guaranteed result.但是,即使您这样做了,也不一定能保证 100% 的结果。 A.network disruption could prevent you from getting the result of a successful write, and the user would never know.答:网络中断可能会阻止您获得成功写入的结果,而用户永远不会知道。

It's up to you which option you choose.选择哪个选项取决于您。 Many developers prefer to allow the SDK do its default work because it's simply easier to assume that the write will eventually succeed.许多开发人员更愿意让 SDK 执行其默认工作,因为更容易假设写入最终会成功。 But if you don't like that assumption, you'll have to code it yourself.但是,如果您不喜欢该假设,则必须自己编写代码。

There is no direct solution for this, as the Firestore writes are automatically sent to the database as soon as the.network is available.对此没有直接的解决方案,因为只要 .network 可用,Firestore 写入就会自动发送到数据库。

So What Can you do?所以,你可以做什么? hmm.唔。

Solutions:解决方案:

1. CHECK FIRST! 1. 先检查! : You can first check if the user has an active.network connection or not and then make read to Firestore. :您可以先检查用户是否有 active.network 连接,然后读取到 Firestore。 This would require you to check for active connection ( do not rely upon just the system's wifi and inte.net connection ).这将需要您检查活动连接(不要仅依赖系统的 wifi 和 inte.net 连接)。
I would suggest you look at this for getting more details, of how to perfectly check for an Active Connection : Network connection / Inte.net access我建议你看看这个以获得更多细节,如何完美地检查活动连接网络连接/ Inte.net 访问

2. USE TRANSACTIONS : You can use a transaction as it fails if there is no inte.net connection. 2. USE TRANSACTIONS :如果没有互联网连接,您可以使用交易失败。 So for your use-case, if the user has an active connection, transaction would be executed and if not, the transaction would fail.因此,对于您的用例,如果用户有活动连接,则交易将被执行,否则,交易将失败。 And most importantly, it will NOT execute automatically.最重要的是,它不会自动执行。

Happy Coding!快乐编码!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Firebase FireStore:如何在使用 addDoc() 添加文档后获取文档快照 - Firebase FireStore : How to get document snapshot after adding document with addDoc() 在 Firebase 模拟器中一次更新后多次读取 Firestore 文档 - Firestore document is read multiple times after a single update in Firebase emulator 如何在一次又一次地点击提交按钮后通过生成不同的文档 ID 将数据添加到 firebase 火库? Android Kotlin - How to add data to the firebase firestore by generating different document id after hitting submit button again and again? Android Kotlin 如何检查在 Java 中的 Firestore 上删除了哪个文档 - Android Studio - How to check which document is deleted on Firestore in Java - Android Studio 如何删除 Firestore 上的特定文档节点(Android Studio) - How to delete a specific document node on Firestore (Android Studio) 如何将 integer 从 firebase firestore 显示到 Android Studio 的 TextView? - How to display integer from firebase firestore to Android Studio's TextView? 一段时间后更新 Firebase Firestore 数据 - Update Firebase Firestore Data After A Certain Amount of Time Java,Firestore - 在 android 工作室中使用 arraylist 的文档 ID 从 Firestore 获取多个文档 - Java, Firestore - Get multiple documents from firestore using an arraylist of document ids in android studio Firestore 在查询后更新文档 - Firestore Update a document after a query 此文档在 firebase firestore 中不存在错误 - This document does not exist error in firebase firestore
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM