为什么我的 SUPABASE 实时监听器偶尔会错过某个事件?

问题描述 投票:0回答:1

我的 iOS 项目中有多个实时侦听器,它们应该实时侦听来自 supabase 的事件。我正在使用当前的 realtimeV2,但有时似乎没有推理,它就不会被触发。其他时候它被解雇得很好。广播也是如此。

我有一个

DataManager
类,我将其注入到
@Environment
中,因此每当应用程序启动时我都会设置大量任务,然后该对象会不断侦听来自数据库的更改以保持用户设备正常运行 -最新数据。

我在这里使用的功能是一个“QRScanner”,它执行以下操作。

  • 设备A显示二维码
  • DeviceB 扫描 QR 并修改 DeviceA 上存在的数据
  • 然后从 DeviceB 更改 DB 上的数据
  • DeviceA 应根据该更新/删除操作进行更新。
  • 有时有效,有时无效。如果没有,则不是由于丢失数据,因为我已确认从未收到消息。

这是我的

init
DataManager
。重申一下。该初始化程序在应用程序启动时调用,然后调度所有侦听器。该对象始终存在于
@Environment
 中的 
root view

public init(_ client: SupabaseClient) {
    self.client = client
    supabaseUser = nil
    loadingRewards = true
    rewards = []
    rewardWeeklySchedules = []
    customerProfiles = []
    rewardTransactions = []
    
    Task.detached(priority: .high) { @MainActor in
        self.supabaseUser = try? await self.client.auth.user()
        try? await self.refreshProfile()
        try? await self.loadWeeklySchedules()
        try? await self.loadRewards()
    }
    
    Task.detached(priority: .background) { @MainActor in
        let channel = await self.client.realtimeV2.channel("public:messages")
        self.singleProfileRealtimeUpdates(channel)
        self.rewardsUpdatedRealtimeUpdate(channel)
        self.rewardScheduleRealtimeUpdate(channel)
        await channel.subscribe()
    }
}

这是我最常遇到问题的实时侦听器之一。我期望发生的是,每当

DeviceB
扫描
DeviceA
的二维码时,它就会显示
DeviceA
的个人资料。他们对其进行更改,并将其推送到数据库。那时它应该触发
DeviceA
的更新,以便与真实数据同步。

func singleProfileRealtimeUpdates(_ channel: RealtimeChannelV2) {
    guard let profile else {
        return
    }
    
    Task.detached(priority: .background) {
        for await update in await channel.postgresChange(UpdateAction.self, table: "reward_profiles", filter: "user_id=eq.\(profile.id)") {
            withAnimation {
                self.profile = try? update.decodeRecord(as: Profile.self, decoder: JSONDecoder())
            }
        }
    }
}

如果您有其他解决方案,除了

Realtime
之外,我100%愿意改变它的工作方式。我唯一可以考虑的是,也许我需要为每个侦听器设置自定义通道,并让它们仅对特定通道进行唯一响应。现在我只对所有这些使用
public:messages

但是我有一个我担心的限制;这是一个白标应用程序,这意味着我们将针对许多不同的客户重新命名它。我可以选择为每个品牌创建自定义频道,或者只是为特定听众创建整体自定义频道,这没有什么区别,但我不知道 SUBABASE 对此有何限制。

swift asynchronous async-await supabase supabase-realtime
1个回答
0
投票

我是 Supabase Mobile SDK 团队的 Guilherme。

可能发生的情况是,您的任务可能在

await channel.subscribe()
调用之后开始,这不会在订阅中包含
postgresChange
,但这种情况会在代码中触发前置条件失败,您是否看到触发了任何前置条件有时?

要解决上述问题,您需要从

postgresChange
中调用
Task.detached
方法,例如:

func singleProfileRealtimeUpdates(_ channel: RealtimeChannelV2) async {
    guard let profile else {
        return
    }

    let updates = await channel.postgresChange(UpdateAction.self, table: "reward_profiles", filter: "user_id=eq.\(profile.id)")

    Task.detached(priority: .background) {
        for await update in updates  {
            withAnimation {
                self.profile = try? update.decodeRecord(as: Profile.self, decoder: JSONDecoder())
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.