swift - Firebase 实时数据,如何将 .child 更改为用户输入的文本字段值

标签 swift firebase firebase-realtime-database

使用 firebase 实时数据库,我正在尝试创建一个 JSON,当用户输入数据而不是使用 AutoId 时,它会从他们的电子邮件地址或“用户”名称中输入数据?

我需要这个的原因是当我收到数据时,我需要知道每个工作链接到哪个电子邮件地址,所以我只能显示与该工作相关的数据。

xcode

正如我在代码中看到的那样,我尝试将 txtfield 添加到每个子项,但这不起作用。

func addedJob (){


    let key = ref.childByAutoId().key!

    //let email = ["email": txtEmail.text! as String]

    let job = ["id": key,
               "shipper": txtShip.text! as String,
               "consignee": txtCon.text! as String,
               "email": txtEmail.text! as String,
               "collection date": txtCol.text! as String,
               "delivery date": txtDel.text! as String,
               "freight": txtFreight.text! as String,
               "reference": txtRef.text! as String,
               "pod": txtPod.text! as String,]


    ref.child(email).setValue(job)

// not working 

ref.child(txtEmail.text! ?? "")

//Still not working this crashes every time

完整的崩溃日志:

Terminating app due to uncaught exception 'InvalidPathValidation', reason: '(child:) Must be a non-empty string and not contain '.' '#' '$' '[' or ']''
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010be481bb __exceptionPreprocess + 331
    1   libobjc.A.dylib                     0x000000010b3e6735 objc_exception_throw + 48
    2   firebarker2019                      0x000000010916e2fd +[FValidation validateFrom:validPathString:] + 253
    3   firebarker2019                      0x00000001090f551f -[FIRDatabaseReference child:] + 239
    4   firebarker2019                      0x000000010904cee5 $S14firebarker201914ViewControllerC8addedJobyyF + 7061
    5   firebarker2019                      0x000000010904b10a $S14firebarker201914ViewControllerC6submityySo8UIButtonCF + 58
    6   firebarker2019                      0x000000010904b14c $S14firebarker201914ViewControllerC6submityySo8UIButtonCFTo + 60
    7   UIKitCore                           0x0000000110553ecb -[UIApplication sendAction:to:from:forEvent:] + 83
    8   UIKitCore                           0x000000010ff8f0bd -[UIControl sendAction:to:forEvent:] + 67
    9   UIKitCore                           0x000000010ff8f3da -[UIControl _sendActionsForEvents:withEvent:] + 450
    10  UIKitCore                           0x000000010ff8e31e -[UIControl touchesEnded:withEvent:] + 583
    11  UIKitCore                           0x000000011058f0a4 -[UIWindow _sendTouchesForEvent:] + 2729
    12  UIKitCore                           0x00000001105907a0 -[UIWindow sendEvent:] + 4080
    13  UIKitCore                           0x000000011056e394 -[UIApplication sendEvent:] + 352
    14  UIKitCore                           0x00000001106435a9 __dispatchPreprocessedEventFromEventQueue + 3054
    15  UIKitCore                           0x00000001106461cb __handleEventQueueInternal + 5948
    16  CoreFoundation                      0x000000010bdad721 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    17  CoreFoundation                      0x000000010bdacf93 __CFRunLoopDoSources0 + 243
    18  CoreFoundation                      0x000000010bda763f __CFRunLoopRun + 1263
    19  CoreFoundation                      0x000000010bda6e11 CFRunLoopRunSpecific + 625
    20  GraphicsServices                    0x0000000113f801dd GSEventRunModal + 62
    21  UIKitCore                           0x000000011055281d UIApplicationMain + 140
    22  firebarker2019                      0x000000010904f227 main + 71
    23  libdyld.dylib                       0x000000010d894575 start + 1
    24  ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) 

最佳答案

这段代码有几个问题:

  • 您的电子邮件常量是一本字典。您不能将字典设置为数据库的子名称。
  • 文本字段的文本属性是字符串。将它们转换为 String 是没有用的。
  • 当您尝试将 txtEmail.text 设置为您强制打开它的子​​项时,因此 nil 合并运算符不执行任何操作。

查看您的崩溃日志,您所面临的问题就很清楚了。您收到的消息是:“(child:) 必须是非空字符串且不包含‘.’ '#' '$' '[' 或 ']'' "这意味着您的文本字段的文本属性必须始终包含一个值,并且不得包含特殊字符。

不幸的是,所有电子邮件地址都包含一个点,这是一个不允许用于 child 姓名的特殊字符。我建议您使用其他值(例如名称、用户名等)。

那么你应该如何解决这个问题:

  • 为了确保文本字段始终有一个值,我不会让用户启动保存到 firebase 数据库,直到他们在文本字段中输入一个值。因此,在您的函数开始上传之前,请检查 textField.text 是否有值。如果它没有显示提醒,让用户知道他们必须在那里输入一个值。
  • 如何检查特殊字符:如上所述,您不应使用电子邮件地址,因为它始终带有一个点。但是,为了安全起见,您可以使用以下函数从所有特殊字符中去除字符串。使用剥离的字符串作为子名称。

    extension String {
    
    var stripped: String {
        let okayChars = Set("abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLKMNOPQRSTUVWXYZ1234567890")
        return self.filter {okayChars.contains($0) }
       }
    }
    

像这样使用它:let strippedString = myString.stripped

询问您是否对此答案有任何疑问。

关于swift - Firebase 实时数据,如何将 .child 更改为用户输入的文本字段值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54763828/

相关文章:

javascript - 当用户提交每个新帖子时,如何为每个新帖子添加时间戳(并在 Firebase 中保存)?

angularjs - 如何防止 Firebase 中出现重复的用户属性?

javascript - 如何使用 ionic 检查配置文件是否存在于 firebase 中?

ios - Nil 与返回类型 'MKOverlayRenderer' 不兼容

swift - Realm 重置模式版本

ios - map 仅显示最后记录的注释

swift - SCNNode 中的 Orientation 和 Rotation 有什么区别

Firebase 深层链接短网址

javascript - react : Can only update a mounted or mounting component

android - 使用 GeoFire 在 android 中填充 Firebase Recycler View