Skip to content

Added FCMError to make handling specific errors easier

Compare
Choose a tag to compare
@MihaelIsaev MihaelIsaev released this 11 Mar 22:58
· 76 commits to master since this release
c49f03d

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: ())
    }
}