错误“客户端在初始同步完成之前尝试使用灵活同步进行连接”

ERROR "Client tried to connect using flexible sync before initial sync is complete"

提问人:Eric Liu 提问时间:7/11/2023 最后编辑:Eric Liu 更新时间:7/11/2023 访问量:131

问:

我是 Swift 和 MongoDB Realm 的新手,所以请耐心等待。我正在尝试使用 Realm 同步到 Atlas 数据库,但我无法显示文档。它一直说同样的错误,即在初始同步完成之前无法使用灵活同步进行连接。请注意,在以下代码示例和日志中,出于隐私原因,我更改了一些内容,例如 appid 和 ip。这是我的代码:

import SwiftUI
import RealmSwift
import UIKit
typealias SwiftApp = SwiftUI.App
typealias RealmApp = RealmSwift.App
typealias SwiftList = SwiftUI.List
typealias RealmList = RealmSwift.List
typealias RealmUser = RealmSwift.User
typealias UserSchema = User

func openSyncedRealm(user: RealmUser) async throws -> Realm {    
        var flexSyncConfig = Globals.app.currentUser!.flexibleSyncConfiguration(initialSubscriptions: { subs in
        subs.append(
            QuerySubscription<UserSchema> {
                try! $0._id == ObjectId(string: user.id)
                })
        }, rerunOnOpen: true)
        
        flexSyncConfig.objectTypes = [User.self]
        print("Got to let realm")
        
        let realm = try await Realm(configuration: flexSyncConfig, downloadBeforeOpen: .never)

        print("finished let realm")
        
        // You must add at least one subscription to read and write from a Flexible Sync realm
        return realm
}

func login(userCredentials: Credentials) async {
    do {
        let user = try await Globals.app.login(credentials: userCredentials)
        print("Successfully logged in user: \(user)")
    } catch {
        print("Error logging in: \(error.localizedDescription)")
    }
}

func registerUser(email: String, password: String, app: RealmApp) async {
    let authInstance: EmailPasswordAuth = EmailPasswordAuth(app: app)
    do {
        try await authInstance.registerUser(email: email, password: password)
        print("Successfully registered user.")
    } catch {
        print("Failed to register: \(error.localizedDescription)")
    }
}



@main
struct Main {
    @MainActor
    static func main() async {
            let dummyuser = UserSchema(
                _id: try! ObjectId(string: Globals.app.currentUser!.id),
                username: "jennierubyjane",
                displayName: "Jennie Kim"
            )
        Globals.app.syncManager.errorHandler = { error,session in
            print("ERROR LOCALIZED DESCRIPTION: \(error.localizedDescription)")
        }
        let email = "[email protected]"
        let password = "BLACKP1NK_in_your_area!"
        await registerUser(email: email, password: password, app: Globals.app)
        await login(userCredentials: Credentials.emailPassword(
            email: email,
            password: password))
        do{
            let realm: Realm = try await openSyncedRealm(user:Globals.app.currentUser!)
            let subscriptions = realm.subscriptions
            print(subscriptions.count)
            subscriptions.update {
                   subscriptions.append(
                      QuerySubscription<UserSchema> {
                          try! $0._id == ObjectId(string: Globals.app.currentUser!.id)
                      })
            } onComplete: { error in
                if let error=error {
                    print("Failed to subscribe: \(error.localizedDescription)")
                }
            }
            print("subscriptions.update ran")
            print(realm.syncSession!)
            
            do {
                try! realm.write {
                    realm.add(dummyuser)
                }
                print("REALM CONNECTION STATE: \(String(describing: realm.syncSession?.connectionState))")
                print("Got to write copy")
                print("Wrote copy")
            } catch {
                if error.localizedDescription.contains("existing primary key value") {
                    print("User already exists")
                } else {
                    throw error
                }
            }
            print("realm.write")
        } catch {
            print("Error opening realm: \(error.localizedDescription)")
        }
        MyApp.main()
    }
}

struct MyApp: SwiftApp {
    var body: some Scene {
        WindowGroup {
            StartupPage()
        }
    }
}


class Globals {
    static var appConfig: AppConfiguration = AppConfiguration(baseURL: "https://realm.mongodb.com")
    
    static var app: RealmApp = RealmApp(id: "MyAPP-asdfghjkl", configuration: appConfig)
    
}
import RealmSwift
import Foundation
import UIKit

class User: Object {
    @Persisted(primaryKey: true) var _id: ObjectId?

    @Persisted var displayName: String = ""

    @Persisted var profilePic: List<Int>

    @Persisted var username: String = ""
    
    convenience init(_id: ObjectId? = nil, username: String, displayName: String) {
        self.init()
        self._id = _id
        self.displayName = displayName
        self.username = username
    }
}

此代码生成以下输出:

Successfully registered user.
Successfully logged in user: <RLMUser: 0x60000283f5c0>
Got to let realm
2023-07-11 15:39:50.303804+0800 MyApp[16275:219469] Info: Realm sync client ([realm-core-13.15.1])
2023-07-11 15:39:50.304049+0800 MyApp[16275:219469] Info: Platform: iOS Darwin 21.6.0 Darwin Kernel Version 21.6.0: Wed Aug 10 14:25:27 PDT 2022; root:xnu-8020.141.5~2/RELEASE_X86_64 x86_64
2023-07-11 15:39:50.388790+0800 MyApp[16275:219522] Info: Connection[1]: Session[1]: Binding '/Users/.../Documents/mongodb-realm/MyApp-asdfghjkl/64ad0745b4aa2cb84f6760b8/flx_sync_default.realm' to ''
2023-07-11 15:39:50.389977+0800 MyApp[16275:219522] Info: Connection[1]: Session[1]: client_reset_config = false, Realm exists = true, client reset = false
2023-07-11 15:39:50.391207+0800 MyApp[16275:219522] Info: Connection[1]: Connecting to 'wss://ws.us-east-1.aws.realm.mongodb.com:443/api/client/v2.0/app/MyApp-asdfghjkl/realm-sync'
finished let realm
1
subscriptions.update ran
<RLMSyncSession: 0x600002813da0> {
    state = 0;
    connectionState = 1;
    realmURL = wss://ws.us-east-1.aws.realm.mongodb.com/api/client/v2.0/app/MyApp-asdfghjkl/realm-sync;
    user = 64ad0745b4aa2cb84f6760b8;
}
REALM CONNECTION STATE: Optional(__C.RLMSyncConnectionState)
Got to write copy
Wrote copy
realm.write
2023-07-11 15:39:50.611646+0800 MyApp[16275:219522] Info: Connected to endpoint '1.1.1.1:111' (from '1.1.1.1:1234')
2023-07-11 15:39:51.558997+0800 MyApp[16275:219522] Info: Connection[1]: Connected to app services with request id: "64ad0747e675f16fea06eade"
2023-07-11 15:39:51.846057+0800 MyApp[16275:219522] Info: Connection[1]: Session[1]: Received: ERROR "Client tried to connect using flexible sync before initial sync is complete" (error_code=229, try_again=true, error_action=Transient)
2023-07-11 15:39:54.072277+0800 MyApp[16275:219522] Info: Connection[1]: Session[1]: Received: ERROR "Client tried to connect using flexible sync before initial sync is complete" (error_code=229, try_again=true, error_action=Transient)
2023-07-11 15:39:58.327243+0800 MyApp[16275:219522] Info: Connection[1]: Session[1]: Received: ERROR "Client tried to connect using flexible sync before initial sync is complete" (error_code=229, try_again=true, error_action=Transient)
2023-07-11 15:40:06.551432+0800 MyApp[16275:219522] Info: Connection[1]: Session[1]: Received: ERROR "Client tried to connect using flexible sync before initial sync is complete" (error_code=229, try_again=true, error_action=Transient)
2023-07-11 15:40:22.774068+0800 MyApp[16275:219522] Info: Connection[1]: Session[1]: Received: ERROR "Client tried to connect using flexible sync before initial sync is complete" (error_code=229, try_again=true, error_action=Transient)
2023-07-11 15:40:52.776975+0800 MyApp[16275:219522] Info: Connection[1]: Disconnected

我已经打开了开发人员模式,UserSchema 模型本质上是从 MongoDB UI 复制和粘贴的,除了方便 init。

在试用了新用户和老用户后,我学到了一些关键的东西:

  1. 写入在本地成功,并在不同的试验中持续存在。如果我尝试使用已经存在的主键编写 UserSchema 对象,那么它会崩溃,指出它无法创建具有相同主键的对象。

  2. 但是,只有当我尝试对同一用户进行 3 次而不是两次时,才会发生崩溃。也许这与用户注册和 objectId 的创建方式有关。

  3. 订阅还会在每个 RealmUser 的试用期中持续存在,并且 subscriptions.count 返回一个非零数字,用于递增每个试用版

  4. 用户已成功注册,我可以在 AppServices UI 上看到它们

  5. 如果我使用该函数,它会输出类似“无法写入文件,因为并非所有客户端更改都集成在服务器中”writeCopy()

我阅读了很多文档,这个错误被称为 ErrorInitialSyncNotCompleted。

此错误表示客户端在初始同步完成之前尝试打开会话。当应用刚刚启用同步,并且仍在构建同步历史记录时,可能会发生这种情况。客户端尝试重新连接,直到此过程完成。然后,此错误将解决,同步开始正常工作。

在我某处读到的论坛上,它说发生此错误是因为日志不够长,因此它完成得太快,因此它“在初始同步之前使用灵活同步进行连接”。如果这是它失败的原因,我不明白也不想依赖这个解决方案。也许可以用异步函数做一些事情来解决这个问题?

这个论坛 https://www.mongodb.com/community/forums/t/client-tried-to-connect-using-flexible-sync-before-initial-sync-is-complete/208025/9 遇到了同样的错误,但在完全不同的上下文中,他们的解决方案只是复制它。

顺便说一句,我是从中国连接的,所以这可能会导致连接问题。

Swift MongoDB 异步 领域

评论


答: 暂无答案