【问题标题】:Local Realm dbs for multiple users多个用户的本地领域数据库
【发布时间】:2020-12-19 11:05:13
【问题描述】:

我正在尝试实现基于用户的领域数据库。因此,每次新用户注册时,都会使用他的 UID(来自 Firebase)创建一个 Realm 文件,或者如果存在,则访问该 Realm。 为此,我为领域调用创建了一个单音并设置领域配置。

我现在的问题是,每次我切换用户时,领域路径都会改变(我在用户登录后打印),但结果读数是相同的,因为用户没有改变,或者领域没有切换。更清楚地说,查询结果给出了相同的数据。

如果我打开实际的 Realms,数据会有所不同。

我在我的 tableView 中看到了这种行为,只是通过加载数据。

我做错了什么?

领域服务:

import Foundation
import RealmSwift
import Firebase


class RealmServices {
    
    private init() {}
    static let shared = RealmServices()
    let userID = Auth.auth().currentUser!.uid
    var realm = try! Realm(configuration: Realm.Configuration.init(
                            fileURL: Realm.Configuration().fileURL!.deletingLastPathComponent().appendingPathComponent("\(Auth.auth().currentUser!.uid).realm")))
    
   
    
    
    func create<T:Object> (_ object: T) {
        do {
            try realm.write {
                realm.add(object)
            }
        } catch {
            post(error)
        }
    }
    
    func update <T: Object>(_ object: T, with dictionary: [String : Any?]) {
        do {
            try realm.write {
                for (key,value) in dictionary {
                    object.setValue(value, forKey: key)
                }
            }
        } catch {
            post (error)
        }
    }
    
    func delete<T:Object> (_ object: T) {
        do {
            try realm.write{
                realm.delete(object)
            }
        } catch {
            post (error)
        }
    }
    
    func post (_ error: Error) {
        NotificationCenter.default.post(name: NSNotification.Name("RealmError"), object: error)
    }
    
    func observeRealmErrors (in vc: UIViewController, completion: @escaping (Error?)-> Void) {
        NotificationCenter.default.addObserver(forName: NSNotification.Name("RealmError"), object: nil, queue: nil) { (Notification) in
            completion(Notification.object as? Error)
        }
    }
    
    func stopObservingError (in vc: UIViewController){
        NotificationCenter.default.removeObserver(vc, name: NSNotification.Name("RealmError"), object: nil)
    }
    
}

【问题讨论】:

  • 如果您使用单例,并且在不重新启动应用程序的情况下切换用户,那么您的单例将始终引用同一个领域。多个用户的单例听起来是个坏主意。
  • 但是新用户一登录,单音的 URL 就会改变,不是吗?
  • 不,每次新用户登录时,您都需要使用适当的配置更新领域属性
  • 如果你在本地设备上严格使用 Realm,单例模式很好——尽管它有它的缺点。但是,您与 Firebase 用户合作的方式可能存在问题。您使用什么过程来验证用户?他们在“切换”用户时如何未经身份验证?此外,更新您的代码以反映指南Configuring a local realm 中显示的内容可能是个好主意,因为我没有看到您使用默认配置填充它
  • @RobertCrabtree 我认为这里的目的是当用户通过身份验证并尝试从领域读取数据时,会根据他们的 firebase uid 使用适当的配置。换句话说,如果 user_a 已登录,则当他们读取领域时,它会在 /appname/user_a.realm 的领域路径中读取领域。每次读取 Realm 时,单例都会设置其 uid 的路径,因此单例模式适用于这种情况。

标签: swift realm


【解决方案1】:

这就是我认为正在发生的事情(我可能完全不在,但让我试一试)

你的 RealmServices 是一个单例并且只初始化一次。它不是每次创建时都会初始化的子类

因此,任何 var 都会在首次​​运行时设置和填充 - realm 属性不会在每次访问时重新初始化。例如,拿这个单例

final class MySingleton {
    private init() {}
    var someUuid = UUID().uuidString
    static let sharedInstance = MySingleton()
}

如您所见, someUuId 是一个“随机”生成的 uuid。如果您访问该属性两次,它会显示相同的值,不会强制更新。

print(MySingleton.sharedInstance.someUuid)
print(MySingleton.sharedInstance.someUuid)

结果

EBE131DE-B574-4CE1-8D74-E680D80A577B
EBE131DE-B574-4CE1-8D74-E680D80A577B

因此,解决方案是每次您希望更改时,将问题中的用户 uid 属性设置为不同的值。这是一个简单的例子

final class RealmService {
    
    private init() {}
    
    var uid: String!
    var usersRealm: Realm! {
        let path = Realm.Configuration().fileURL!.deletingLastPathComponent().appendingPathComponent("\(uid!).realm")
        let realm = try! Realm(configuration: Realm.Configuration.init(fileURL: path))
        return realm
    }

    static let sharedInstance = RealmService()
}

这就是它的名称;在本例中,我们将 item0 写入 user0 的领域,将 item1 写入 user1 的领域:

RealmService.sharedInstance.uid = "uid_0"
let user0Realm = RealmService.sharedInstance.usersRealm!

let item0 = ItemClass(name: "item 0")

try! user0Realm.write {
    user0Realm.add(item0)
}

RealmService.sharedInstance.uid = "uid_1"
let user1Realm = RealmService.sharedInstance.usersRealm!

let item1 = ItemClass(name: "item 1")

try! user1Realm.write {
    user1Realm.add(item1)
}

结果是为每个用户创建一个领域,其中 item0 在 user0 的领域中,而 item1 在 user1 的领域中

【讨论】:

  • 我明天会试试你的版本,问题是在我的情况下它也在创建文件,但在第一次登录后它没有加载正确的文件。第二个登录用户看到了相同的数据(并且考虑了 table.reloads 和类似的东西)。可能是它已初始化,我需要“关闭它”或“重新初始化”它。我会带来更新。
  • @Radu 酷。这只是我的猜测——它可能也与用户登录/退出 firebase 的方式有关。随时通知我。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-09
相关资源
最近更新 更多