Firebase Realtime Data, как изменить .child на значение текстового поля, которое вводит пользователь - PullRequest
0 голосов
/ 19 февраля 2019

Используя базу данных Firebase в реальном времени, я пытаюсь создать JSON, который, когда пользователь вводит данные вместо использования AutoId, вводит их со своего адреса электронной почты или имени пользователя?

Причина, по которой мне это нужно, заключается в том, что когда я получаю данные, мне нужно знать, на какой адрес электронной почты ссылается каждое задание, чтобы я мог показывать только данные, относящиеся к этому заданию.

xcode

Как видно из кода, я пытался добавить поле txt для каждого дочернего элемента, однако это не работает.

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) 

Ответы [ 2 ]

0 голосов
/ 19 февраля 2019

Есть несколько проблем с этим кодом:

  • Ваша константа электронной почты - это словарь.Вы не можете установить словарь в качестве имени дочернего элемента базы данных.
  • Текстовые свойства текстовых полей являются строками.Бессмысленно разыгрывать их как String.
  • Когда вы пытаетесь установить txtEmail.text в качестве дочернего, вы принудительно разворачиваете его, поэтому оператор слияния nil ничего не делает.ясно.Сообщение, которое вы получаете: « (child :) Должно быть непустой строкой и не содержать '.''#' '$' '[' or ']' ' "Это означает, что свойство text вашего текстового поля всегда должно содержать значение и не должно содержать специальных символов.

    К сожалению, все адреса электронной почты содержатточка, которая является специальным символом, недопустимым для дочерних имен.Я предлагаю вам использовать другое значение (например, имя, имя пользователя и т. Д.).

    Итак, как вы должны это исправить:

    • Чтобы убедиться, что текстовое поле всегда имеет значение, я быне позволяйте пользователю инициировать сохранение в базе данных firebase, пока он не введет значение в текстовое поле.Поэтому, прежде чем ваша функция начнет загрузку, проверьте, имеет ли значение textField.text.Если на нем не отображается предупреждение, информирующее пользователя о том, что он должен ввести значение.
    • Как проверить наличие специальных символов: как я уже говорил выше, не следует использовать адрес электронной почты,потому что в нем всегда есть точка.Однако в целях безопасности вы можете использовать следующую функцию, чтобы отделить строку от всех специальных символов.Используйте раздетую строку в качестве дочернего имени.

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

    Используйте это так: let strippedString = myString.stripped

    Спросите, есть ли у вас какие-либо вопросы с этим ответом.

0 голосов
/ 19 февраля 2019

Как ошибка, указывающая, что

reason: '(child:) Must be a non-empty string and not contain '.' '#' '$' '[' or ']''

, поэтому вы не можете создать ключ, который содержит '.' '#' '$' '[' or ']' этих символов.

Единственное решение, которое я могу придумать, это то, что вы можете преобразовать emailстрока к base64Encoded, и как только вы вернете ее с сервера, вы можете получить свою электронную почту с base64Encoded строки.

Рассмотрите код ниже:

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()
    }
}

let email = "test1@gmail.com"

let base64Encoded = email.base64EncodedString // dGVzdDFAZ21haWwuY29t
let normalEmailFromBase64 = String(base64Encoded: base64Encoded) //test1@gmail.com

И вы можете установить данные с помощью

ref.child(base64Email).updateChildValues(job)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...