FireBase for SwiftUI小纸条(二)

在SwiftUI中使用Realtime Database写入数据

·

2 min read

创建FireBase中的Realtime Database实例

首先我们需要在FireBase项目管理控制台中找到Realtime Database:

image.png

点击创建数据库,选择一个数据库所处的位置:

image.png

接下来需要为数据库设置安全规则,因为我们是用来测试,先设置为测试模式,将来再考虑安全规则:

image.png

这样就完成了一个实时数据库实例的创建了。当你创建完成一个数据库实例后,需要得到你新的Xcode的GoogleService-info.plist文件。首先点击项目概览右侧的项目设置:

image.png

然后向下滚动,可以看到你的应用:

image.png

这里可以下载到更新后的plist文件,如果更新到Xcode后,你会发现这个plist文件里有一个DATABASE_URL的条目出现:

image.png

为你的项目加入Realtime Database支持

首先按照FireBase for SwiftUI小纸条(一)初始化你的项目。如果你之前已经创建好了,但是没有在项目中勾选上Realtime Database所需要的FirebaseDatabaseFirebaseDatabaseSwift条目,哪么你可以在项目中自己去添加:

image.png

写入数据

简单写入

写入一个数据其实非常简单,与我们向一个属性set一样。首先,我们写一个ViewModel,为View提供支持:

import Foundation
import FirebaseDatabase
import FirebaseDatabaseSwift

class WriteViewModel: ObservableObject{
    private let ref = Database.database().reference()

    func writeNewValue(value: String){
        ref.setValue(value)
    }
}

我们使用Database.database().reference()得到去操作数据库的一个接口引用实例,然后调用ref.setValue(value)来将数据存储至实时数据库。setValue支持写入字符串(NSString)、数字(NSNumber)、字典(NSDictionary)和数组(NSArray)。

接下来,我们准备一个View来让我们在App里操作write行为:

import SwiftUI

struct WriteView: View {
    @StateObject var vm = WriteViewModel()
    @State var content: String = ""

    var body: some View {
        VStack{
            Text("Write Content")
            TextEditor(text: $content)
                .border(.black)
            Button{
                vm.writeNewValue(value: content)
            }label: {
                Text("Push")
            }.buttonStyle(.borderedProminent)
        }
        .padding()
    }
}

来看看效果吧:

write.gif

自动创建子节点

在Realtime Database数据库中存储的是一个JSON,但是为了不大规模的处理全量数据,引入了节点的概念,我们可以先来试试自动创建子节点的感觉,修改下ViewModel:

import Foundation
import FirebaseDatabase

class WriteViewModel: ObservableObject{
    private let ref = Database.database().reference()

    func writeNewValue(value: String){
        ref.childByAutoId().setValue(value)
    }
}

通过childByAutoId()我们可以得到一个新的唯一子节点,效果如下:

childByAudoId.gif

指定节点写入数据

如果想要向自己指定的子节点写入数据,只需要指定节点名称就好:

ref.child("Game1").setValue(value)

image.png

多级子节点

如果想要多级子节点,其实也非常方便:

ref.child("Game1").child("user1").setValue(value)

image.png

写入对象

只需要将一个class支持序列化成JSON,哪么我们就可以非常简单的将一个对象存入实时数据库中了。首先,我们准备一个class定义,并扩展它可以序列化成为JSON:

class User: Encodable{
    var username: String = ""
    var level: Int = 1
}

extension Encodable{
    var toDictionary: [String: Any]?{
        guard let data = try? JSONEncoder().encode(self) else{
            return nil
        }
        return try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: Any]
    }
}

再将写入改为以下代码:

        let user = User()
        user.username=value
        ref.child(user.username).setValue(user.toDictionary)

你会看到这样的结果:

image.png

写入数组

如果我们想将User变为一个数组,如何存入数据库中呢?只需要一个数组即可,但是因为User是一个class,并不是一个JSON的基础数据类型,所以我们还是需要借助toDictionary来存储:

        var users = [Any]()

        for i in 1...3{
            let user = User()
            user.username="\(value)\(i)"
            user.level=i
            users.append(user.toDictionary as Any)
        }
        ref.childByAutoId().setValue(users)

存入的数值就像这样:

image.png

Firebase的变动是非常频繁的,文档里也会遇到很多不足,但是比起苹果的文档,已经好了很多了。这里留下一些我自己也常用到的页面(不确定是不是一直有效,如果有问题请告诉我):

Did you find this article valuable?

Support 老房东 by becoming a sponsor. Any amount is appreciated!