Firebase生成的数据表无法稳定显示
Posted
技术标签:
【中文标题】Firebase生成的数据表无法稳定显示【英文标题】:Data table generated from Firebase cannot be displayed stably 【发布时间】:2021-04-29 16:40:37 【问题描述】:我需要开发一个具有排行榜功能的移动应用。排行榜只显示在一个选项卡上,但是,每次我从另一个选项卡返回此页面时,排行榜总是立即消失(请看这个screen record)。有没有办法让数据稳定显示?
这是我的代码 sn-p:
// LeaderboardView.swift
import SwiftUI
struct Leaderboard: View
@ObservedObject private var users = UserViewModel()
var body: some View
// ...
NavigationView
List(users.topFiveUsers)
user in
VStack
HStack
Text(verbatim: user.name).font(.headline)
Text(verbatim: String(user.xp)).font(.subheadline)
.navigationTitle(Text("Leaderboard"))
Spacer()
.background(Color.white)
struct Leaderboard_Previews: PreviewProvider
static var previews: some View
Leaderboard()
// UserViewModel.swift
import Foundation
import Firebase
import FirebaseFirestore
class UserViewModel: ObservableObject
@Published var topFiveUsers = [User]()
private var db = Firestore.firestore().collection("Users")
public init()
let top5 = db.order(by: "xp", descending: true).limit(to: 5)
top5.addSnapshotListener (QuerySnapshot, error) in
guard let documents = QuerySnapshot?.documents else
print("Document is empty")
return
self.topFiveUsers = documents.map
(QueryDocumentSnapshot) -> User in
let data = QueryDocumentSnapshot.data()
let xp = data["xp"]
let name = data["username"]
return User(name:name as? String ?? "", xp:xp as? Int ?? 0)
// User.swift
import SwiftUI
import Firebase
class User : ObservableObject, Identifiable
@Published var name = ""
@Published var bio = ""
@Published var interest = ""
@Published var level = 1
@Published var xp = 0
@Published var email = ""
@Published var image_Data = Data(count: 0)
@Published var picker = false
let ref = Firestore.firestore()
@Published var isLoading = false
@AppStorage("status") var status = false
// common init
init()
//initializer for leaderboard collection
init(name: String, xp: Int)
self.name = name
self.xp = xp
self.level = User.xp2Level(xp: xp)
// ContentView.swift
struct ContentView: View
init()
UITabBar.appearance().isHidden = true
@State var centerX : CGFloat = 0
@State var goToHome = false
@State var edge = UIApplication.shared.windows.first?.safeAreaInsets
// @Environement(.verticalSizeClass) var size
var body: some View
ZStack
if goToHome
NavigationView
CustomTabView(centerX: $centerX)
.navigationBarTitleDisplayMode(.inline)
.navigationBarHidden(true)
else
OnBoardScreen()
.onReceive(NotificationCenter.default.publisher(for:Notification.Name("Success")), perform:
_ in withAnimationself.goToHome = true
)
struct CustomTabView : View
//swich tabs
@State var selectedTab = "home"
@Binding var centerX : CGFloat
var body : some View
ZStack(alignment: Alignment(horizontal: .center, vertical: .bottom))
TabView(selection: $selectedTab)
Home()
.tag("home")
Leaderboard()
.tag("Leaderboard")
Pal()
.tag("profile")
// .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
.ignoresSafeArea(.all, edges: .all)
// Spacer()
HStack(spacing: 0)
ForEach(tabs, id: \.self) image in
GeometryReader reader in
TabButton(image: image, centerX: $centerX, rect:reader.frame(in:.global), selectedTab: $selectedTab)
//setting initial curve
.onAppear(perform:
if image == tabs.first
centerX = reader.frame(in: .global).midX
)
.frame(width: 50, height: 30)
if image != tabs.last Spacer(minLength: 0)
.padding(.horizontal, 30)
// .padding(.top)
.padding(.vertical, 17)
.padding(.bottom, 20)
.padding(.bottom, UIApplication.shared.windows.first?.safeAreaInsets.bottom == 0 ? 15: 0)
.background(Color("5324FF").clipShape(AnimatedShape(centerX: centerX)))
.shadow(color: Color.blue.opacity(0.1), radius: 5, x: 0, y: -5)
// .ignoresSafeArea(.all, edges: .all)
.ignoresSafeArea(.all, edges: .all)
【问题讨论】:
这个问题与您处理显示视图的方式有关。用户对象、firebase 和排行榜本身的代码与问题无关。请发布代码,显示您如何显示不同的标签项。 感谢您的建议,我已经编辑了我的问题。请参考。 同意 xTwisteDx 所说的 - 问题在于您如何处理选项卡视图的选定状态。我建议将其设置在一个较小的复制案例中,这样您就不会被所有其他代码分心。另外,请不要手动映射 Firestore 数据 - 改用 Codable。我为此写了一份综合指南:peterfriese.dev/firestore-codable-the-comprehensive-guide。此外,请确保将 Firestore 文档 ID 与用户的 id 属性进行映射,以使其真正可识别。 【参考方案1】:即使@State 有效,您也应该使用@StateObject。如果使用@State,SwiftUI 可能会随机销毁 Object。
@StateObject private var users = UserViewModel()
【讨论】:
【参考方案2】:我将视图文件中变量users
的属性从ObservedObject
更改为State
。然后桌子就稳定了。
【讨论】:
以上是关于Firebase生成的数据表无法稳定显示的主要内容,如果未能解决你的问题,请参考以下文章
HashMap 为空,因此我无法从 Firebase 数据库获取模拟器中显示的数据
无法显示从Firebase提取的数据到reactjs Webapp中
本地写入是不是以与生成的顺序相同的顺序提交到 firebase
我想从firebase实时数据库中显示recyclerview android上的数据..但我无法将动态数据加载到适配器数组中