Skip to content

setAuth() not working when subscribing to broadcast database changes #713

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
baalexander opened this issue Apr 30, 2025 · 3 comments
Open
Labels
bug Something isn't working

Comments

@baalexander
Copy link

I have been following the tutorial for Subscribing to Database Changes with the Swift client. The Swift client does not receive the database messages when triggered (like a record is updated), however, the JS client does receive the database messages.

I believe it's because supabase.realtimeV2.setAuth() does not send JWT credentials to channels because of this guard statement:

guard tokenToSend != mutableState.accessToken else {
    return
}

Spelunking session

  1. Initialize SupabaseClient (let supabase = SupabaseClient(...))
  2. On init, SupabaseClient calls listenForAuthEvents()
  3. listenForAuthEvents() calls handleTokenChanged(...)
  4. handleTokenChanges() calls await realtimeV2.setAuth(accessToken)

The problem seems to be that since await realtimeV2.setAuth(accessToken) is called in the initializing of SupabaseClient, it's triggered before we can subscribe to any channels. So if we have code like this:

let channel = supabase.channel("topic:id")
let broadcastStream = channel.broadcastStream(event: "UPDATE")
await channel.subscribe()
await supabase.realtimeV2.setAuth()
Task {
    for await message in broadcastStream {
        print("Message received", message)
    }

The setAuth() call does not send JWT auth to the channels, because the guard gets kicked in since the accessToken hasn't changed from initializing SupabaseClient:

realtimeV2.setAuth():

public func setAuth(_ token: String? = nil) async {
  var tokenToSend = token

  if tokenToSend == nil {
    tokenToSend = try? await options.accessToken?()
  }

  // 👇 guard kicks in, so the for channel in channels loop never get fired
  guard tokenToSend != mutableState.accessToken else {
    return
  }

  mutableState.withValue { [token] in
    $0.accessToken = token
  }

  for channel in channels.values {
    if channel.status == .subscribed {
      options.logger?.debug("Updating auth token for channel \(channel.topic)")
      await channel.push(
        ChannelEvent.accessToken,
        payload: ["access_token": token.map { .string($0) } ?? .null]
      )
    }
  }
}

Now it's very possible I'm just doing something wrong or completely missed a piece, but it seems like it's impossible to push accessTokens to channels since SupabaseClient sets the accessToken at initialization. Please let me know if I'm off base though and there's another reason!

@baalexander baalexander added the bug Something isn't working label Apr 30, 2025
@grdsdev
Copy link
Collaborator

grdsdev commented May 1, 2025

Hi @baalexander I'm not sure this is the issue here, when subscribing to a channel it fetches the access token as in:

accessToken: await socket._getAccessToken(),

The token gets sent when subscribing, and the setAuth is used only if token changes, to update the subscribed channels.


I'll go through the tutorial for validating it, thanks!

@baalexander
Copy link
Author

Thanks for the quick response @grdsdev. That makes sense that it sends the accessToken on subscribe. So the for channel in channels loop in setAuth is just for when the user gets a new accessToken. Got it.

Yes, please let me know if you're successful with the Swift client and the tutorial!

@grdsdev
Copy link
Collaborator

grdsdev commented Jun 2, 2025

Hi @baalexander, sorry for the delay on this.

I'm updating our SlackClone example to use broadcast changes. You can follow along in this still-draft PR: #723

Also, from what I'm seeing in your code sample, you're missing setting the channel to private. Broadcast changes only work for private channels. This is how you do it:

Let me know if that solves your issue.

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants