应用架构咨询:首次用结构体+Firebase开发遇数据加载异常
Hey there! It sounds like you're hitting a common snag when working with structs and Firebase, especially with state persistence across app restarts. Let's walk through the most likely causes and fixes for your loadUserInfo() returning empty data after a restart.
1. First: Ensure Your User Struct is Properly Serializable/Deserializable
Since you're using structs with Firebase, the first thing to check is whether your struct conforms to the Codable protocol. Firebase relies on this to convert your structs to/from JSON data stored in the database. If you skipped this step, the data might save temporarily in memory (which is why it works the first time) but fail to properly persist or reload from disk.
Here's how to set this up correctly:
// Example User struct with Codable conformance struct User: Codable { let uid: String let displayName: String? let location: String // Add any other properties you need for your user }
When writing to Firebase, use try! JSONEncoder().encode(user) to convert the struct to data, and when reading, use try! JSONDecoder().decode(User.self, from: data) to parse it back into a struct.
2. Check if Global.refString is Persisted Across App Restarts
Your Global.refString is set via a UIPicker with 6 hardcoded locations, but when you restart the app, this value is likely reset to an empty string or a default that doesn't match your Firebase data path. That’s why loadUserInfo() works the first time (you’ve selected a location in the picker) but fails on restart.
Fixes here:
- Persist the selected location: Use
UserDefaultsto save the last selected location when the user picks it from the UIPicker. Then, on app launch, initializeGlobal.refStringwith the saved value (or a default location if none exists).// Save when user selects a location UserDefaults.standard.set(selectedLocation, forKey: "SelectedUserLocation") // Initialize on app launch Global.refString = UserDefaults.standard.string(forKey: "SelectedUserLocation") ?? "DefaultLocation" // Replace with one of your hardcoded locations - Verify the value at runtime: Add a print statement in
loadUserInfo()to check whatGlobal.refStringis set to when the app restarts. If it’s empty, that’s definitely the issue.
3. Validate Your Firebase Read/Write Logic
Since the first load works, your write logic is probably okay for in-memory use, but let’s confirm it’s correctly persisting to Firebase:
- When creating a user, ensure you’re writing the
locationfield to the correct Firebase node (e.g.,users/{uid}) with the exact value fromGlobal.refString. - When loading users, make sure your query is targeting the right path and filtering by the
locationfield correctly. For example:
Note: Usingfunc loadUserInfo() { let ref = Database.database().reference().child("users") // Filter users by the selected location let query = ref.queryOrdered(byChild: "location").queryEqual(toValue: Global.refString) query.observe(.value) { snapshot in var users = [User]() for child in snapshot.children { if let snapshot = child as? DataSnapshot, let userData = snapshot.value as? [String: Any], let user = try? JSONDecoder().decode(User.self, from: JSONSerialization.data(withJSONObject: userData)) { users.append(user) } } // Update your UI with the users array print("Loaded \(users.count) users for location: \(Global.refString)") } }observe(.value)instead ofobserveSingleEvent(of: .value)ensures you get real-time updates and the data reloads automatically when the app restarts (as long as the refString is correct).
4. Check Firebase Persistence Settings
Firebase Realtime Database enables disk persistence by default, but if you’ve disabled it, data won’t persist across app restarts. Double-check you haven’t added this line anywhere:
Database.database().isPersistenceEnabled = false
If you have, remove it or set it to true to enable offline persistence.
Quick Debugging Tips
- Use the Firebase Console to manually check if user data with the correct
locationvalues is being saved. - Add print statements in
loadUserInfo()to log the snapshot value andGlobal.refString—this will show you if the query is returning no data because the refString is wrong or the data doesn’t exist.
Hopefully these steps help you track down the issue! Let me know if you need to dive deeper into any of these areas.
内容的提问来源于stack exchange,提问作者ggtechllc

