Is it possible to retrieve a newly created record that triggered a CKQuerySubscription in CloudKit?

58 Views Asked by At

After my app receives a notification indicating that a new record has been created, I am able to extract the recordID from the notification payload. However, when I attempt to retrieve the record using the extracted recordID, I am unable to access it because the record has not yet been fully created in CloudKit at the time of the notification reception.

I could add add a time delay to give CloudKit enough time to add the record but that feels hacky. Should I just not fetch the record using the recordID from the notification payload?

//  AppDelegate.swift

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    
    guard let notification = CKNotification(fromRemoteNotificationDictionary: userInfo) else { return completionHandler(.failed) }
    
    // Check notification type
    if notification.notificationType == .query, let result = notification as? CKQueryNotification {
        // Check which subscription was triggered
        if result.subscriptionID == .newFriendRequestSubscription {
            // Extract data from notification payload
            if let recordID = result.recordID {
                Task {
                    await handleFriendRequest(recordID: recordID)
                }
            }
        } else {
            print("Unknown subscription id")
        }
    }
    
    return completionHandler(.newData)
}

func handleFriendRequest(recordID: CKRecord.ID) async {
    do {
        // Fetch friend request record
        let senderID = CKRecord.Reference(recordID: recordID, action: .none)
        let userID = try await container.userRecordID()
        let receiverID = CKRecord.Reference(recordID: userID, action: .none)
        let predicate = NSPredicate(format: "senderID == %@ AND receiverID == %@", senderID, receiverID)
        let query = CKQuery(recordType: "FriendRequest", predicate: predicate)
        let (results, _) = try await database.records(matching: query, resultsLimit: 1)
        
        // This fails because record is not created by time user receives this notification so there is no record to fetch
        if let record = try results.first?.1.get() {
            print("Successfully got friend request")
            self.newPendingRequest = FriendRequest(record: record)
        } else {
            print("Friend request not found")
        }
        
    } catch {
        print("Erroring fetching friend request record: \(error)")
    }
}
0

There are 0 best solutions below