Merge pull request #781 from mpretty-cyro/fix/push-notification-reregistration

Update the SyncPushTokensJob to reregister every 12 hours
pull/786/head
RyanZhao 2 years ago committed by GitHub
commit 4bec546d81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -11,6 +11,7 @@ public enum SyncPushTokensJob: JobExecutor {
public static let maxFailureCount: Int = -1 public static let maxFailureCount: Int = -1
public static let requiresThreadId: Bool = false public static let requiresThreadId: Bool = false
public static let requiresInteractionId: Bool = false public static let requiresInteractionId: Bool = false
private static let maxFrequency: TimeInterval = (12 * 60 * 60)
public static func run( public static func run(
_ job: Job, _ job: Job,
@ -34,45 +35,44 @@ public enum SyncPushTokensJob: JobExecutor {
return return
} }
// Push tokens don't normally change while the app is launched, so checking once during launch is // Push tokens don't normally change while the app is launched, so you would assume checking once
// usually sufficient, but e.g. on iOS11, users who have disabled "Allow Notifications" and disabled // during launch is sufficient, but e.g. on iOS11, users who have disabled "Allow Notifications"
// "Background App Refresh" will not be able to obtain an APN token. Enabling those settings does not // and disabled "Background App Refresh" will not be able to obtain an APN token. Enabling those
// restart the app, so we check every activation for users who haven't yet registered. // settings does not restart the app, so we check every activation for users who haven't yet
guard job.behaviour != .recurringOnActive || !UIApplication.shared.isRegisteredForRemoteNotifications else { // registered.
//
// It's also possible for a device to successfully register for push notifications but fail to
// register with Session
//
// Due to the above we want to re-register at least once every ~12 hours to ensure users will
// continue to receive push notifications
//
// In addition to this if we are custom running the job (eg. by toggling the push notification
// setting) then we should run regardless of the other settings so users have a mechanism to force
// the registration to run
let lastPushNotificationSync: Date = UserDefaults.standard[.lastPushNotificationSync]
.defaulting(to: Date.distantPast)
guard
job.behaviour == .runOnce ||
!UIApplication.shared.isRegisteredForRemoteNotifications ||
Date().timeIntervalSince(lastPushNotificationSync) >= SyncPushTokensJob.maxFrequency
else {
deferred(job) // Don't need to do anything if push notifications are already registered deferred(job) // Don't need to do anything if push notifications are already registered
return return
} }
Logger.info("Retrying remote notification registration since user hasn't registered yet.") Logger.info("Re-registering for remote notifications.")
// Determine if we want to upload only if stale (Note: This should default to true, and be true if
// 'details' isn't provided)
let uploadOnlyIfStale: Bool = ((try? JSONDecoder().decode(Details.self, from: job.details ?? Data()))?.uploadOnlyIfStale ?? true)
// Get the app version info (used to determine if we want to update the push tokens)
let lastAppVersion: String? = AppVersion.sharedInstance().lastAppVersion
let currentAppVersion: String? = AppVersion.sharedInstance().currentAppVersion
// Perform device registration
PushRegistrationManager.shared.requestPushTokens() PushRegistrationManager.shared.requestPushTokens()
.then(on: queue) { (pushToken: String, voipToken: String) -> Promise<Void> in .then(on: queue) { (pushToken: String, voipToken: String) -> Promise<Void> in
let lastPushToken: String? = Storage.shared[.lastRecordedPushToken]
let lastVoipToken: String? = Storage.shared[.lastRecordedVoipToken]
let shouldUploadTokens: Bool = (
!uploadOnlyIfStale || (
lastPushToken != pushToken ||
lastVoipToken != voipToken
) ||
lastAppVersion != currentAppVersion
)
guard shouldUploadTokens else { return Promise.value(()) }
let (promise, seal) = Promise<Void>.pending() let (promise, seal) = Promise<Void>.pending()
SyncPushTokensJob.registerForPushNotifications( SyncPushTokensJob.registerForPushNotifications(
pushToken: pushToken, pushToken: pushToken,
voipToken: voipToken, voipToken: voipToken,
isForcedUpdate: shouldUploadTokens, isForcedUpdate: true,
success: { seal.fulfill(()) }, success: { seal.fulfill(()) },
failure: seal.reject failure: seal.reject
) )
@ -94,6 +94,7 @@ public enum SyncPushTokensJob: JobExecutor {
public static func run(uploadOnlyIfStale: Bool) { public static func run(uploadOnlyIfStale: Bool) {
guard let job: Job = Job( guard let job: Job = Job(
variant: .syncPushTokens, variant: .syncPushTokens,
behaviour: .runOnce,
details: SyncPushTokensJob.Details( details: SyncPushTokensJob.Details(
uploadOnlyIfStale: uploadOnlyIfStale uploadOnlyIfStale: uploadOnlyIfStale
) )

@ -44,6 +44,7 @@ public enum SNUserDefaults {
case lastOpenGroupImageUpdate case lastOpenGroupImageUpdate
case lastOpen case lastOpen
case lastGarbageCollection case lastGarbageCollection
case lastPushNotificationSync
} }
public enum Double: Swift.String { public enum Double: Swift.String {

Loading…
Cancel
Save