SwiftUI - 更新 Firebase 实时数据库上的数据
Posted
技术标签:
【中文标题】SwiftUI - 更新 Firebase 实时数据库上的数据【英文标题】:SwiftUI - Update data on Firebase's Realtime database 【发布时间】:2021-09-26 02:42:39 【问题描述】:我已成功将数据显示到 UI,但我希望用户能够在点击“保存”按钮时再次更新我的数据。希望你能帮助我!
简介
I have successfully displayed the data to the UI, but I want the user to be able to update my data again when tapping the "Save" button . Hope you can help me!
【问题讨论】:
您在哪一行按下保存按钮? @ElTomato 我刚刚成功渲染了 UI。我还没有实现保存按钮 向我们展示您正在使用的代码的完整示例,包括您希望在 UI 中更新数据的位置以及任何相关的 UI 上下文。 @workingdog 我已经更新了上面的代码 【参考方案1】:有很多方法可以实现您想要的。这只是一种方法,通过
将profileViewModel
传递给EditProfile
:
class ProfileViewModel: ObservableObject
@Published var user = Profile(id: "", image: "", birthDay: "", role: [], gender: "", name: "")
private var ref: DatabaseReference = Database.database().reference()
func fetchData(userId: String? = nil)
// 8hOqqnFlfGZTj1u5tCkTdxAED2I3
ref.child("users").child(userId ?? "default").observe(.value) [weak self] (snapshot) in
guard let self = self,
let value = snapshot.value else return
do
print("user: \(value)")
self.user = try FirebaseDecoder().decode(Profile.self, from: value)
catch let error
print(error)
func saveUser()
// save the user using your ref DatabaseReference
// using setValue, or updateChildValues
// see https://firebase.google.com/docs/database/ios/read-and-write
struct EditProfile: View
@ObservedObject var profileViewModel: ProfileViewModel // <--- here
var body: some View
VStack
Text(profileViewModel.user.name) // <--- you probably meant TextField
.font(.custom("Poppins-Regular", size: 15))
.foregroundColor(Color.black)
Text("\(profileViewModel.user.birthDay)!")
.font(.custom("Poppins-Regular", size: 22))
.fontWeight(.bold)
.foregroundColor(Color.black)
Text("\(profileViewModel.user.gender)")
.font(.custom("Poppins-Regular", size: 22))
.fontWeight(.bold)
.foregroundColor(Color.black)
Text(profileViewModel.user.role.first ?? "")
.font(.custom("Poppins-Regular", size: 22))
.fontWeight(.bold)
.foregroundColor(Color.black)
Button(action:
// save the profileViewModel.user to database
profileViewModel.saveUser() // <--- here
)
Text("Save")
.padding()
struct CategoriesView: View
@ObservedObject var viewModel = SectionViewModel()
@EnvironmentObject var loginViewModel : LoginViewModel
@StateObject var profileViewModel = ProfileViewModel()
var body: some View
ZStack
VStack (alignment: .leading, spacing:0)
EditProfile(profileViewModel: profileViewModel) // <--- here
.padding()
.padding(.bottom,-10)
.onAppear()
self.viewModel.fetchData()
profileViewModel.fetchData(userId: loginViewModel.session?.uid)
EDIT1:关于更新的代码。
在您的新代码中,ProfileHost
中您没有传递 ProfileViewModel。
使用:
NavigationLink(destination: ProfileEditor(profileViewModel: viewModel))
ProfileRow(profileSetting: profile)
在ProfileEditor
中将profile
替换为profileViewModel.user
您可能需要调整 profileItem
并将其放入 .onAppear ...
中。像这样的:
struct ProfileEditor: View
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
@ObservedObject var profileViewModel: ProfileViewModel
@EnvironmentObject var loginViewModel: LoginViewModel
let profileLabel: [String] = ["Name", "Account", "Gender", "Role", "Email"]
@State var profileItem: [String] = []
@State var profileEditorRow: [ProfileEditorItem] = []
var body: some View
VStack
ForEach(profileEditorRow) editor in
if editor.id == 5
ProfileEditorRow(editor: editor, showLastLine: true)
else
ProfileEditorRow(editor: editor, showLastLine: false)
Button("Save")
profileViewModel.updateData(userId: loginViewModel.session?.uid)
.onAppear
profileItem = [profileViewModel.user.name,
profileViewModel.user.birthDay,
profileViewModel.user.gender,
profileViewModel.user.role.first ?? "",
profileViewModel.user.birthDay]
for n in 1...5
profileEditorRow.append(ProfileEditorItem(id: n, label: profileLabel[n-1], item: profileItem[n-1]))
EDIT2:更新函数
func updateData()
ref.("users").child(user.id).updateChildValues([
"name": user.name,
"birthDay": user.birthDay,
"gender": user.gender,
"role": user.role.first ?? ""])
并在ProfileEditor
中使用它:
Button("Save")
profileViewModel.updateData()
【讨论】:
我关注了你,但它不起作用 究竟是什么不起作用?你有一些错误吗?我怀疑您使用的代码不是您向我们展示的代码,例如,EditProfile
不会编辑任何内容。最好能编辑您的问题并准确显示您使用的代码。
因为分很多层,所以想给大家总结一下。我已经更新了上面所有的当前代码
我已经更新了我的答案,以反映您显示的新代码。
你能在我的代码中编辑它吗?以上是关于SwiftUI - 更新 Firebase 实时数据库上的数据的主要内容,如果未能解决你的问题,请参考以下文章
将 Firebase 实时数据库与 SwiftUI 列表一起使用 - 清除列表
SwiftUI / Firebase:我可以使用@Published 向 Firebase 数据库发送和接收单个值吗?
SwiftUI - 将存储中图像文件的路径移动到 Firebase 上的实时数据库 [重复]
在 SwiftUI 中读取带有子节点的 Firebase 实时数据库父节点的问题