使用 firebase 实时数据库,我正在尝试创建一个 JSON,当用户输入数据而不是使用 AutoId 时,它会从他们的电子邮件地址或“用户”名称中输入数据?
我需要这个的原因是当我收到数据时,我需要知道每个工作链接到哪个电子邮件地址,所以我只能显示与该工作相关的数据。
正如我在代码中看到的那样,我尝试将 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/