Hi there,
we try to implement the “Restricted News Feed” example in Swift from the Flexible Sync Permissions Guide.
We couldn’t check out the example via the template, so we had to copy the backend related things from the guide to a newly created app. (enabled email authentication, added the authentication trigger, the function to subscribe to someone else, enabled custom userdata etc…)
The backend seems to work as it should.
On client side we implemented a simple comment Object, with String Data to display:
class Comment: Object, ObjectKeyIdentifiable {
@Persisted(primaryKey: true) public var _id: String = UUID().uuidString
@Persisted public var ownerId: String
@Persisted public var comment: String
}
User now can log in to the client and create comments - and sync it (works as expected). And they could subscribe to other users comments like in the example from the guide (with the same server function as in the guide). On the server we can see that the data is correct.
The problem now: on client side nothing happens when a user subscribes to another users comment. The other users comments won’t be synced…
Only when the user deletes his app from the device, reinstalls it and logs in with the same user as before - then he can see his comments and the comments from the user he subscripted to.
Here is the code for initializing the realm in SwiftUI:
let app = App(id: "xxxxxxx")
@main
struct TestSyncApp: SwiftUI.App {
var body: some Scene {
WindowGroup {
if let app = app {
AppView(app: app)
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
else {
Text("No RealmApp found!")
}
}
}
}
struct AppView: View {
@ObservedObject var app: RealmSwift.App
var body: some View {
if let user = app.currentUser {
let config = user.flexibleSyncConfiguration(initialSubscriptions: { subs in
if subs.first(named: "Comment") != nil {
return
}
else {
subs.append(QuerySubscription<Comment>(name: "Comment"))
}
})
OpenSyncedRealmView()
.environment(\.realmConfiguration, config)
.environmentObject(user)
}
else {
LoginView()
}
}
}
struct OpenSyncedRealmView: View {
@AutoOpen(appId: "xxxxxxx", timeout: 4000) var realmOpen
var body: some View {
switch realmOpen {
case .connecting,.waitingForUser,.progress(_):
ProgressView("waiting ...")
case .open(let realm):
RealmContentView()
.environment(\.realm, realm)
case .error(let error):
Text("opening realm error: \(error.localizedDescription)")
}
}
}
And the code for displaying the comments:
struct RealmContentView: View {
@Environment(\.realm) var realm: Realm
@ObservedResults(Comment.self) var comments
@State var subscribeToEmail: String = ""
var body: some View {
VStack {
HStack {
Spacer()
Text("SubscribeTo:")
TextField("Email", text: $subscribeToEmail)
Button {
if let user = app.currentUser {
Task {
do {
_ = try await user.functions.subscribeToUser([AnyBSON(subscribeToEmail)])
}
catch {
print("Function call failed - Error: \(error.localizedDescription)")
}
}
}
} label: {
Image(systemName: "mail")
}
Text("New Comment:")
Button {
let dateFormatter : DateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MMM-dd HH:mm:ss.SSSS"
let date = Date()
let dateString = dateFormatter.string(from: date)
let newComment = Comment()
newComment.comment = "\(app.currentUser!.id) - \(dateString)"
newComment.ownerId = app.currentUser!.id
$comments.append(newComment)
} label: {
Image(systemName: "plus")
}
}
.padding()
if comments.isEmpty {
Text("No Comments here!")
}
else {
List {
ForEach(comments) { comment in
Text(comment.comment)
.listRowBackground(comment.ownerId == app.currentUser!.id ? Color.white: Color.green)
}
}
.listStyle(.automatic)
}
}
}
}
Did we miss something? Do we have to manage/handle subscriptions in a different way? Or have we found a bug?
Thanks for any help!