Хранение пользовательских объектов с массивом пользовательских объектов в Firebase: Swift - PullRequest
1 голос
/ 07 марта 2019

Как мне выполнить эту настройку в базе данных Firebase Realtime с помощью Swift:

Иерархия базы данных

enter image description here

В настоящее время я делаю это, сохраняя больший элемент (со свойствами familyKey, geofences и phoneNumbers) как пользовательский объект. Кроме того, само свойство geofences является массивом пользовательских объектов. Я получаю NSException, делая это описанным способом. Как еще я мог бы сделать это?

    var tempGeofences = [GeofenceData]()
    tempGeofences.append(GeofenceData(name: "Hello WOrld", latitude: 0, longitude: 0, radius: 1000))

    let familyKey:String = String(Int.random(in: 1000...99999))
    let uid:String = Auth.auth().currentUser!.uid
    let phoneNumber = "1111111111"
    let parent = Parent(phoneNumber: phoneNumber, familyKey: familyKey, geofences: tempGeofences)

    databaseRef.child(uid).setValue(parent)

В этой строке выдается исключение NSE:

databaseRef.child(uid).setValue(parent)

Родительский класс:

import Foundation

public class Parent {
var phoneNumber: String?
var familyKey: String?
var geofences: [GeofenceData]?

init() {
    self.phoneNumber = ""
    self.familyKey = ""
    self.geofences = nil
}

init(phoneNumber: String?, familyKey: String?, geofences:[GeofenceData]) {
    self.phoneNumber = phoneNumber
    self.familyKey = familyKey
    self.geofences = geofences
}

public func getPhoneNumber() -> String {
    return phoneNumber!
}

public func getFamilyKey() -> String {
    return familyKey!
}

public func getGeofences() -> [GeofenceData] {
    return geofences!
}

// left off here, trying to send geofence object to firebase
public func toDictionary() -> Any {
    return ["familyKey": familyKey, "geofences": geofences, "phoneNumber": phoneNumber]
}

}

И класс GeofenceData:

import Foundation
import Firebase

public class GeofenceData {
var name: String?
var latitude: Double?
var longitude: Double?
var radius: Float?

init() {

}

init(name: String?, latitude: Double, longitude: Double, radius: Float) {
    self.name = name
    self.latitude = latitude
    self.longitude = longitude
    self.radius = radius
}

// left off here, trying to send geofence object to firebase
public func toDictionary() -> Any {
    return ["name": name, "latitude": latitude, "longitude": longitude, "radius": radius]
}

public func getName() -> String {
    return name!
}

public func getLatitude() -> Double {
    return latitude!
}

public func getLongitude() -> Double {
    return longitude!
}

public func getRadius() -> Float {
    return radius!
}

public func setName(name: String?) {
    self.name = name
}

public func saveToFirebase(reference: DatabaseReference) {
    let dict = ["name": name, "latitude": latitude, "longitude": longitude, "radius": radius] as Any
    reference.child("geofences").child("0").setValue(dict)
}

}

1 Ответ

1 голос
/ 09 марта 2019

Parent не является объектом, который распознает Firebase, поэтому выдает ошибку.

Руководство по Firebase Чтение и запись данных показывает четыре типа объектов, которые могут быть записаны; Строка, число, словарь, массив.

Одним из решений является встраивание в класс функции, которая возвращает данные, которые вы хотите записать.

public class Parent {
    var phoneNumber: String?
    var familyKey: String?
    var geofences: [GeofenceData]?

    init() {
        self.phoneNumber = ""
        self.familyKey = ""
        self.geofences = nil
    }

    //other init functions

    func getParentDict() -> [String: Any] {

        let geoDict = ["name": name,
                       "latitude": latitude,
                       "longitude": longitude,
                       "radius": radius
        ]

        let zeroNode = ["0": geoDict]

        let dictForFirebase: [String: Any] = [
            "phoneNumber": phoneNumber,
            "familyKey": familyKey,
            "geofences": zeroNode
        ]

        return dictForFirebase
    }
}

и на практике

var tempGeofences = [GeofenceData]()
tempGeofences.append(GeofenceData(name: "Hello WOrld", latitude: 0, longitude: 0, radius: 1000))

let familyKey:String = String(Int.random(in: 1000...99999))
let uid:String = Auth.auth().currentUser!.uid
let phoneNumber = "1111111111"
let parent = Parent(phoneNumber: phoneNumber, familyKey: familyKey, geofences: tempGeofences)
let parentDict = parent.getParentDict
databaseRef.child(uid).setValue(parentDict)

Однако одной проблемой является дочерний узел с ключом «0». Похоже, вы можете использовать массив. Если есть хорошая причина, это хорошо, но обычно есть гораздо лучшие альтернативы использованию массивов в базах данных NoSQL. См. Старый, но все еще точный пост Firebase под названием Массивы злы

EDIT:

За комментарий / вопрос 'как добавить еще один дочерний узел после узла "0" *

Предположим, что мы знаем родительский узел, qSaEE ..., давайте добавим узел "1"

let parentNode = "qSaEE..."
let geofenceRef = firebaseRef.child(parentNode).child("geofences")

let geoDict = ["name": name,
               "latitude": latitude,
               "longitude": longitude,
               "radius": radius
               ]

let oneNode = ["1": geoDict]

geofenceNode.setValue(oneNode)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...