如何使用Firebase

时间:2016-04-27 16:37:21

标签: firebase

我注意到如果我在Firebase中执行查询并且无法访问数据库服务器,则回调会一直等待(或直到服务器再次可访问)。

如果这种行为对于所使用的异步方法非常自然,那么有一种简单的方法可以指定超时,这样您就可以告知用户状态。

有没有这样的选择,我只是错过了 - 或者它真的丢失了? 或者您将如何解决这个问题?

5 个答案:

答案 0 :(得分:3)

截至目前,这些听众没有超时概念。一种选择是自己管理超时。

当我还想在加载内容时显示进度对话框时,我就是这样做的。

    private void showProgressDialog(boolean show, long time) {
    try {
        if (progressDialog != null) {
            if (show) {
                progressDialog.setMessage("Cargando...");
                progressDialog.show();
                new Handler().postDelayed(new Runnable() {
                    public void run() {
                        if(progressDialog!=null && progressDialog.isShowing()) {
                            progressDialog.dismiss();
                            Toast.makeText(ActPreguntas.this, "Couldn't connect, please try again later.", Toast.LENGTH_LONG).show();
                        }
                    }
                }, time);
            } else {
                progressDialog.dismiss();
            }
        }
    }catch(IllegalArgumentException e){
    }catch(Exception e){
    }
}

因此,当您向Firebase发出请求时,请调用showProgressDialog(true,5000),如果对话框仍然存在,则会在5秒后因为无法连接而导致您按照超时执行操作。

在Firebase侦听器的回调中,你执行showProgressDialog(false,0)

希望它有所帮助。

答案 1 :(得分:2)

你可以自己管理一个定时器控制器,在x秒后删除你的firebase引用的监听器。它非常简单,例如在android中只有一行代码。

您可以看到网络代码(Detaching Callbacks部分): https://www.firebase.com/docs/web/guide/retrieving-data.html

或用于android(Detaching Callbacks部分): https://www.firebase.com/docs/android/guide/retrieving-data.html#section-detaching

IOS的​​相同部分;)

答案 2 :(得分:0)

我建议只使用一个线程?

允许您自己从线程实例中分配对Firebase的调用,然后在极少数情况下,写入Firebase的时间太长 ,您可以取消线程吗?

let thread = NSThread(target:self, selector:#selector(uploadToFirebase), object:nil)

。 。

func uploadToFirebase(data: Dictionary) {

    // Do what you need to here. Just an example

    db.collection("posts").document("some unique post id").setData([
        "name": "John",
        "likes": 0
    ]) { err in
        if let err = err {
            print("Error writing document: \(err)")
        } else {
            print("Document successfully written!")
        }
    }

}

然后只创建一个计时器,如果该计时器触发则取消该线程。如果不是,只需取消计时器。

答案 3 :(得分:0)

如果您使用的是Firebase SDK v6.5.0及更高版本,则可以使用 FirebaseOptions的setConnectTimeout https://firebase.google.com/docs/reference/admin/java/reference/com/google/firebase/FirebaseOptions.Builder.html#setConnectTimeout(int))。

示例:

Integer connectTimeoutinMillis = 6000; //6 seconds
FirebaseOptions firebaseOptions = FirebaseOptions.builder()
 .setCredentials(credentials)
 .setDatabaseUrl(Application.firebaseSDKDatabaseUrl)
 .setConnectTimeout(connectTimeoutinMillis)
 .build();
FirebaseApp.initializeApp(firebaseOptions);

答案 4 :(得分:0)

这是我针对Firebase iOS SDK的解决方案,这可能对其他人有帮助:

extension DatabaseReference {

    func observe(_ eventType: DataEventType, timeout: TimeInterval, with block: @escaping (DataSnapshot?) -> Void) -> UInt {

        var handle: UInt!

        let timer = Timer.scheduledTimer(withTimeInterval: timeout, repeats: false) { (_) in
            self.removeObserver(withHandle: handle)
            block(nil)
        }

        handle = observe(eventType) { (snapshot) in
            timer.invalidate()
            block(snapshot)
        }

        return handle
    }

}

用法:

database.child("users").observe(.value, timeout: 30) { (snapshot) in

    guard let snapshot = snapshot else {
        // Timeout!
        return
    }

    // We got data within the timeout, so do something with snapshot.value
}