【问题标题】:Swift Firebase QueryOrderedSwift Firebase QueryOrdered
【发布时间】:2017-06-23 17:50:50
【问题描述】:

我有一个营业地点的注册页面,并且正在比较纬度和经度是否与数据库中的任何现有子项匹配。此代码有时有效,然后停止工作。当它停止工作时,我会按下“创建帐户操作”并且什么都不会发生。我添加了一个 print("Sign Up Button Tapped Firebase Problem") 所以我知道该按钮实际上正在触发。为什么这段代码有时有效,有时无效?我的问题的解决方案是什么?谢谢。

@IBAction func createAccountAction(_ sender: Any) {
    let email = self.emailTextField.text!
    let password = self.passwordTextField.text!

    if firstName.text == "" {
        CommonUtils.sharedUtils.showAlert(self, title: "Error", message: "Please Enter Your First Name.")
    }
    if lastName.text == "" {
        CommonUtils.sharedUtils.showAlert(self, title: "Error", message: "Please Enter Your Last Name.")
    }
    if companyPosition.text == "" {
        CommonUtils.sharedUtils.showAlert(self, title: "Error", message: "Please Enter Your Company Position.")
    }
    if businessName.text == "" {
        CommonUtils.sharedUtils.showAlert(self, title: "Error", message: "Please Enter The Business Name.")
    }
    if businessStreet.text == "" {
        CommonUtils.sharedUtils.showAlert(self, title: "Error", message: "Please Enter The Business's Street.")
    }
    if businessCity.text == "" {
        CommonUtils.sharedUtils.showAlert(self, title: "Error", message: "Please Enter The City.")
    }
    if businessState.text == "" {
        CommonUtils.sharedUtils.showAlert(self, title: "Error", message: "Please Enter The State.")
    }
    if businessZIP.text == "" {
        CommonUtils.sharedUtils.showAlert(self, title: "Error", message: "Please Enter The ZIP.")
    }
    if businessPhone.text == "" {
        CommonUtils.sharedUtils.showAlert(self, title: "Error", message: "Please Enter The Business's Phone.")
    }
    if businessWebsite.text == "" {
        CommonUtils.sharedUtils.showAlert(self, title: "Error", message: "Please Enter The Business Website.")
    }
    if businessLatitude.text == "" {
        CommonUtils.sharedUtils.showAlert(self, title: "Error", message: "Please Enter The Business Latitude.")
    }
    if businessLongitude.text == "" {
        CommonUtils.sharedUtils.showAlert(self, title: "Error", message: "Please Enter The Business Longitude.")
    }

    print("Sign Up Button Tapped Firebase problem")

    self.ref.child("Businesses").queryOrdered(byChild: "businessLatitude").queryEqual(toValue: self.businessLatitude.text!).observeSingleEvent(of: .value, with: { snapshot in
        if (snapshot.value! is NSNull) {
            print("Not Found - GOOD")
            if email != "" && password != "" && self.firstName.text != "" && self.lastName.text != "" && self.companyPosition.text != "" && self.businessName.text != "" && self.businessStreet.text != "" && self.businessCity.text != "" && self.businessState.text != "" && self.businessZIP.text! != "" && self.businessPhone.text != "" && self.businessWebsite.text != "" && self.businessLatitude.text != "" && self.businessLongitude.text != "" {
                // search for businessLatitude
                CommonUtils.sharedUtils.showProgress(self.view, label: "Registering...")
                FIRAuth.auth()?.createUser(withEmail: email, password: password, completion:  { (user, error) in
                    if error == nil {
                        FIREmailPasswordAuthProvider.credential(withEmail: email, password: password)
                        self.ref.child("Businesses").child(user!.uid).setValue(["firstName":self.firstName.text!,"lastName":self.lastName.text!, "companyPosition":self.companyPosition.text!,"businessName":self.businessName.text!, "businessStreet":self.businessStreet.text!, "businessCity":self.businessCity.text!, "businessState":self.businessState.text!, "businessZIP":self.businessZIP.text!, "businessPhone":self.businessPhone.text!, "businessWebsite":self.businessWebsite.text!,"businessLatitude":self.businessLatitude.text!, "businessLongitude":self.businessLongitude.text!, "approvalStatus":self.isApproved, "email":email ])
                        CommonUtils.sharedUtils.hideProgress()
                        let photoViewController = self.storyboard?.instantiateViewController(withIdentifier: "BusinessProfile")
                        self.navigationController?.pushViewController(photoViewController!, animated: true)
                    } else {
                        DispatchQueue.main.async(execute: {() -> Void in
                            CommonUtils.sharedUtils.hideProgress()
                            CommonUtils.sharedUtils.showAlert(self, title: "Error", message: (error?.localizedDescription)!)
                        })
                    }
                })
            } else {
                let alert = UIAlertController(title: "Error", message: "Enter email & password!", preferredStyle: .alert)
                let action = UIAlertAction(title: "OK", style: .default, handler: nil)
                alert.addAction(action)
            }
            } else {
            print(snapshot.value!)
            if let snapshots = snapshot.children.allObjects as? [FIRDataSnapshot] {
                for snap in snapshots {
                    let thisLongitude = snap.childSnapshot(forPath: "businessLongitude").value as! String
                    if thisLongitude == self.businessLongitude.text! {
                        // handle repeated location
                        if snap.exists() == true {
                            DispatchQueue.main.async(execute: {() -> Void in
                                CommonUtils.sharedUtils.hideProgress()
                                CommonUtils.sharedUtils.showAlert(self, title: "Error", message: "This Place Already Is Registered")
                            })
                        }
                    }
                }
            }
        }
    })
}

更多信息

如果我像这样设置这个代码(下面的代码)并运行它,它可以工作,但它会检查用户注册后是否存在相同的“businessLatitude”并将用户保存到数据库中。然后,当我将它设置回上面的代码时,上面的代码运行并进行检查,而不将用户注册到数据库中(正是我想要的)。为什么它在我做触发器之后运行?哈哈

if email != "" && password != "" && self.firstName.text != "" && self.lastName.text != "" && self.companyPosition.text != "" && self.businessName.text != "" && self.businessStreet.text != "" && self.businessCity.text != "" && self.businessState.text != "" && self.businessZIP.text! != "" && self.businessPhone.text != "" && self.businessWebsite.text != "" && self.businessLatitude.text != "" && self.businessLongitude.text != "" {
        // search for businessLatitude
        CommonUtils.sharedUtils.showProgress(self.view, label: "Registering...")
        FIRAuth.auth()?.createUser(withEmail: email, password: password, completion:  { (user, error) in
            if error == nil {
                FIREmailPasswordAuthProvider.credential(withEmail: email, password: password)
                self.ref.child("Businesses").child(user!.uid).setValue(["firstName":self.firstName.text!,"lastName":self.lastName.text!, "companyPosition":self.companyPosition.text!,"businessName":self.businessName.text!, "businessStreet":self.businessStreet.text!, "businessCity":self.businessCity.text!, "businessState":self.businessState.text!, "businessZIP":self.businessZIP.text!, "businessPhone":self.businessPhone.text!, "businessWebsite":self.businessWebsite.text!,"businessLatitude":self.businessLatitude.text!, "businessLongitude":self.businessLongitude.text!, "approvalStatus":self.isApproved, "email":email ])
                CommonUtils.sharedUtils.hideProgress()
                let photoViewController = self.storyboard?.instantiateViewController(withIdentifier: "BusinessProfile")
                self.navigationController?.pushViewController(photoViewController!, animated: true)
            } else {
                DispatchQueue.main.async(execute: {() -> Void in
                    CommonUtils.sharedUtils.hideProgress()
                    CommonUtils.sharedUtils.showAlert(self, title: "Error", message: (error?.localizedDescription)!)
                })
            }
        })
    } else {
        let alert = UIAlertController(title: "Error", message: "Enter email & password!", preferredStyle: .alert)
        let action = UIAlertAction(title: "OK", style: .default, handler: nil)
        alert.addAction(action)
    }

    self.ref.child("Businesses").queryOrdered(byChild: "businessLatitude").queryEqual(toValue: self.businessLatitude.text!).observeSingleEvent(of: .value, with: { snapshot in
        if (snapshot.value! is NSNull) {
            print("Not Found - GOOD")
            } else {
            print(snapshot.value!)
            if let snapshots = snapshot.children.allObjects as? [FIRDataSnapshot] {
                for snap in snapshots {
                    let thisLongitude = snap.childSnapshot(forPath: "businessLongitude").value as! String
                    if thisLongitude == self.businessLongitude.text! {
                        // handle repeated location
                        if snap.exists() == true {
                            DispatchQueue.main.async(execute: {() -> Void in
                                CommonUtils.sharedUtils.hideProgress()
                                CommonUtils.sharedUtils.showAlert(self, title: "Error", message: "This Place Already Is Registered")
                            })
                        }
                    }
                }
            }
        }
    })
}

更多信息

我刚刚将 Firebase 中的“读取”+“写入”规则更改为“真”。我一直在阅读这如何构成安全风险?到目前为止这是有效的,但我正在测试它是否会像以前一样停止工作。我会保持更新的....

{
"rules": {
".read": "true",
".write": "true",
"Businesses": {
  "$Businesses_id" : {
    ".indexOn": "businessLatitude"
  }
}
}
}

设置断点时的编译器图片

This is the compiler when the code won't work and I set a breakpoint at the top line

This is what the compiler looks like after I do the "Hack" to make it work. What is different is "Provider Data/API Key/ User Id"

【问题讨论】:

  • 尝试指定出现错误的代码的确切部分,以使其更具可读性。
  • 在发布问题之前,您需要进行一些故障排除 - 这样您可能会发现问题,或者至少告诉我们哪一行代码不工作或崩溃。只需在 self.ref 行添加断点,运行应用程序,点击按钮,然后逐行执行,直到找到问题。此外,您可能需要重新考虑所有这些 if 语句,就好像有多个空字段一样,它会显示很多警报,这不是一个好的用户体验。
  • 我添加了更多信息,如果您需要更多信息,请告诉我
  • 我是不是发现了 firebase 的 bug 之类的????
  • 有人知道吗???

标签: ios swift firebase firebase-realtime-database firebase-authentication


【解决方案1】:

我不确定问题中是否有足够的信息来具体回答,但消除一些变量可能会导致解决方案。因此,让我们尝试通过简化来生成答案...

我所做的是在 Firebase 中创建一个节点以进行如下测试:

app_name
   Businesses
     bus_0
       businessLatitude: "thing"
     bus_1
       businessLatitude: "test"
     bus_2
       businessLatitude: "stuff"

然后我创建了一个全新的 Firebase 项目并将以下代码粘贴到 viewDidLoad 函数中。此代码是从您的问题中复制和粘贴的,消除了闭包中的大部分“东西”。

//self.ref 是我的 firebase 的参考。

override func viewDidLoad() {

     self.ref.child("Businesses").queryOrdered(byChild: "businessLatitude")
                                 .queryEqual(toValue: "test")
                                 .observeSingleEvent(of: .value, with: { snapshot in
         if (snapshot.value! is NSNull) {
             print("nothing found")
         } else {
             print("found it!")
             print(snapshot)
         }
     })
}

然后构建并运行应用程序。输出是:

found it!
Snap (Businesses) {
    "bus_1" =     {
        businessLatitude = test;
    };
}

基于此结果,代码本身可以正常工作,因此肯定有其他因素影响该过程。可能正在调用另一个方法,或者可能存在异步代码问题。

我建议做同样的事情 - 创建一个新项目并使用上面发布的代码,看看它是否有效。如果是这样,我会注释掉你项目中的很多代码,并尝试尽可能简单地运行它,尝试减少变量的数量。然后让它工作,并一次添加一些代码,直到它停止工作。

【讨论】:

  • 谢谢,我会试一试,看看我能想出什么
  • 如何在规则中保存当前的“businessLatitude”和“businessLongitude”?我的规则会影响为什么我的查询没有被调用吗?
  • @LukasBimba “保存”是什么意思?规则就是这样 - 它们为您的数据提供安全性,并且可以允许或不允许访问特定的数据节点。它们不会影响为什么不调用您的查询 - 但是,它们可以阻止数据被读取/写入。 Firebase 始终提供反馈 - 作为错误条件或控制台/Xcode 日志中的响应。例如,如果我们采用您的规则并将 read 设置为 false 并尝试使用应用程序进行读取,[Firebase/Database][I-RDB038012] Listener at /Businesses failed: permission_denied 将打印到控制台.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-03
相关资源
最近更新 更多