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

Swift Firebase实时数据,如何将.child更改为用户输入的文本字段值,swift,firebase,firebase-realtime-database,Swift,Firebase,Firebase Realtime Database,使用firebase实时数据库,我试图创建一个JSON,当用户输入数据而不是使用AutoId时,它会从他们的电子邮件地址或“用户名”中输入数据 我之所以需要它,是因为当我收到数据时,我需要知道每个工作链接的电子邮件地址,这样我就只能显示与该工作相关的数据 正如代码中所示,我试图将txtfield添加到每个child中,但是这不起作用 func addedJob (){ let key = ref.childByAutoId().key! //let email = ["e

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

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

正如代码中所示,我试图将txtfield添加到每个child中,但是这不起作用

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) 

作为错误表明

reason: '(child:) Must be a non-empty string and not contain '.' '#' '$' '[' or ']''
因此,您不能创建包含
'.#'$''['或']'.
此字符的密钥

我能想到的一个解决方案是,您可以将
email
string转换为
base64Encoded
,一旦从服务器取回,您就可以从
base64Encoded
string取回电子邮件

考虑以下代码:

extension String {
    init?(base64Encoded: Data) {
        guard let data = Data(base64Encoded: base64Encoded) else { return nil }
        self.init(data: data, encoding: .utf8)
    }
    init?(base64Encoded: String) {
        guard let data = Data(base64Encoded: base64Encoded) else { return nil }
        self.init(data: data, encoding: .utf8)
    }
    var data: Data {
        return Data(utf8)
    }
    var base64EncodedData: Data {
        return data.base64EncodedData()
    }
    var base64EncodedString: String {
        return data.base64EncodedString()
    }
}


您可以使用

ref.child(base64Email).updateChildValues(job)

作为错误表明

reason: '(child:) Must be a non-empty string and not contain '.' '#' '$' '[' or ']''
因此,您不能创建包含
'.#'$''['或']'.
此字符的密钥

我能想到的一个解决方案是,您可以将
email
string转换为
base64Encoded
,一旦从服务器取回,您就可以从
base64Encoded
string取回电子邮件

考虑以下代码:

extension String {
    init?(base64Encoded: Data) {
        guard let data = Data(base64Encoded: base64Encoded) else { return nil }
        self.init(data: data, encoding: .utf8)
    }
    init?(base64Encoded: String) {
        guard let data = Data(base64Encoded: base64Encoded) else { return nil }
        self.init(data: data, encoding: .utf8)
    }
    var data: Data {
        return Data(utf8)
    }
    var base64EncodedData: Data {
        return data.base64EncodedData()
    }
    var base64EncodedString: String {
        return data.base64EncodedString()
    }
}


您可以使用

ref.child(base64Email).updateChildValues(job)

此代码存在一些问题:

  • 你的电子邮件常量是一本字典。不能将字典设置为数据库子级的名称
  • 文本字段的文本属性是字符串。把它们当作绳子扔是没有用的
  • 当您尝试将txtEmail.text设置为子对象时,您会强制将其展开,因此nil合并运算符不会执行任何操作
看看你的事故记录,你面临的问题很清楚。您收到的消息是:“(子:)必须是非空字符串,且不包含“.”#“$”[”或“]””这意味着您的文本字段的文本属性必须始终包含值,且不得包含特殊字符

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

因此,您应该如何解决此问题:

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

    extension String {
    
    var stripped: String {
        let okayChars = Set("abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLKMNOPQRSTUVWXYZ1234567890")
        return self.filter {okayChars.contains($0) }
       }
    }
    
像这样使用:
let strippedString=myString.stripped


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

此代码存在一些问题:

  • 你的电子邮件常量是一本字典。不能将字典设置为数据库子级的名称
  • 文本字段的文本属性是字符串。把它们当作绳子扔是没有用的
  • 当您尝试将txtEmail.text设置为子对象时,您会强制将其展开,因此nil合并运算符不会执行任何操作
看看你的事故记录,你面临的问题很清楚。您收到的消息是:“(子:)必须是非空字符串,且不包含“.”#“$”[”或“]””这意味着您的文本字段的文本属性必须始终包含值,且不得包含特殊字符

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

因此,您应该如何解决此问题:

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

    extension String {
    
    var stripped: String {
        let okayChars = Set("abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLKMNOPQRSTUVWXYZ1234567890")
        return self.filter {okayChars.contains($0) }
       }
    }
    
像这样使用:
let strippedString=myString.stripped


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

您的故障日志是什么?你有没有试过
ref.child(txtEmail.text!)updateChildValues(job)
libc++abi.dylib:以NSException(lldb)类型的未捕获异常终止检查我更新的注释。是的,仍然崩溃,我用完整的崩溃日志更新了我的问题什么是
txtEmail.text您的崩溃日志是什么?你有没有试过
ref.child(txtEmail.text!)updateChildValues(job)
libc++abi.dylib:以NSException(lldb)类型的未捕获异常终止检查我更新的注释。是的,仍然崩溃,我用完整的崩溃日志更新了我的问题什么是
txtEmail.text