Releases: MihaelIsaev/FCM
Releases · MihaelIsaev/FCM
New properties for `FCMAndroidNotification` (#18)
Thanks to @nerzh ❤️
Add `sendMessage` to the FCMProvider protocol
Add sendMessage
to the FCMProvider protocol so it can be mocked in tests (#13)
Added FCMError to make handling specific errors easier
Many thanks to @grahamburgsma
So, now we can parse Google and FCM errors, let's take a look how
return try fcm.sendMessage(container.make(Client.self), message: message).transform(to: ()).catchFlatMap { error in
guard let googleError = error as? GoogleError, let fcmError = googleError.fcmError else {
return container.eventLoop.newFailedFuture(error: error)
}
switch fcmError.errorCode {
case .unspecified: break
case .invalid: break
case .unregistered: break
case .senderIDMismatch: break
case .quotaExceeded: break
case .apnsAuth: break
case .unavailable: break
case .internal: break
}
}
And now we can delete token if we're getting unregistered
error like this:
return try fcm.sendMessage(container.make(Client.self), message: message).transform(to: ()).catchFlatMap { error in
guard let googleError = error as? GoogleError, let fcmError = googleError.fcmError else {
return container.eventLoop.newSucceededFuture(result: ())
}
switch fcmError.errorCode {
case .unregistered: // drop token only if unregistered
return container.requestPooledConnection(to: .psql).flatMap { conn in
return Self.query(on: conn).filter(\.firebaseToken == token).first().flatMap { model in
defer { try? container.releasePooledConnection(conn, to: .psql) }
guard var model = model else { return container.eventLoop.newSucceededFuture(result: ()) }
model.firebaseToken = nil
return model.save(on: conn).transform(to: ())
}.always {
try? container.releasePooledConnection(conn, to: .psql)
}
}
default:
return container.eventLoop.newSucceededFuture(result: ())
}
}
Throw an error if unable to get access token
Related to #6
Fixing access token refreshing
This is fixing unexpected behavior when the server is unable to send pushes after an hour after launch.