diff --git a/FirebaseMessaging/CHANGELOG.md b/FirebaseMessaging/CHANGELOG.md index cf83a783db6..795539da1dd 100644 --- a/FirebaseMessaging/CHANGELOG.md +++ b/FirebaseMessaging/CHANGELOG.md @@ -1,3 +1,6 @@ +# Unreleased +- [fixed] Improve token-fetch failure logging with detailed error info. (#13997). + # 11.0.0 - [fixed] Completed Messaging's transition to NSSecureCoding (#12343). diff --git a/FirebaseMessaging/Sources/Token/FIRMessagingTokenFetchOperation.m b/FirebaseMessaging/Sources/Token/FIRMessagingTokenFetchOperation.m index ffb3fdb736c..0bc1e79c3b0 100644 --- a/FirebaseMessaging/Sources/Token/FIRMessagingTokenFetchOperation.m +++ b/FirebaseMessaging/Sources/Token/FIRMessagingTokenFetchOperation.m @@ -172,6 +172,11 @@ - (void)handleResponseWithData:(NSData *)data FIRMessagingLoggerDebug(kFIRMessagingMessageCodeInternal001, @"%@", failureReason); responseError = [NSError messagingErrorWithCode:kFIRMessagingErrorCodeInvalidIdentity failureReason:failureReason]; + } else { + FIRMessagingLoggerDebug(kFIRMessagingMessageCodeTokenFetchOperationRequestError, + @"Token fetch got an error from server: %@", errorValue); + responseError = [NSError messagingErrorWithCode:kFIRMessagingErrorCodeUnknown + failureReason:errorValue]; } } if (!responseError) { diff --git a/FirebaseMessaging/Tests/UnitTests/FIRMessagingTokenOperationsTest.m b/FirebaseMessaging/Tests/UnitTests/FIRMessagingTokenOperationsTest.m index 0459a8d3e38..a785b7f5b98 100644 --- a/FirebaseMessaging/Tests/UnitTests/FIRMessagingTokenOperationsTest.m +++ b/FirebaseMessaging/Tests/UnitTests/FIRMessagingTokenOperationsTest.m @@ -185,7 +185,7 @@ - (void)testThatTokenOperationsAuthHeaderStringMatchesCheckin { [FIRURLSessionOCMockStub stubURLSessionDataTaskWithResponse:expectedResponse - body:[self dataForResponseWithValidToken:YES] + body:[self dataForResponseWithValidToken:@""] error:nil URLSessionMock:self.URLSessionMock requestValidationBlock:^BOOL(NSURLRequest *_Nonnull sentRequest) { @@ -315,7 +315,7 @@ - (void)testThatOptionsDictionaryIsIncludedWithFetchRequest { [FIRURLSessionOCMockStub stubURLSessionDataTaskWithResponse:expectedResponse - body:[self dataForResponseWithValidToken:YES] + body:[self dataForResponseWithValidToken:@""] error:nil URLSessionMock:self.URLSessionMock requestValidationBlock:^BOOL(NSURLRequest *_Nonnull sentRequest) { @@ -368,7 +368,7 @@ - (void)testServerResetCommand { [FIRURLSessionOCMockStub stubURLSessionDataTaskWithResponse:expectedResponse - body:[self dataForResponseWithValidToken:NO] + body:[self dataForResponseWithValidToken:@"RST"] error:nil URLSessionMock:self.URLSessionMock requestValidationBlock:^BOOL(NSURLRequest *_Nonnull sentRequest) { @@ -392,6 +392,55 @@ - (void)testServerResetCommand { }]; } +- (void)testTooManyRegistrationsError { + XCTestExpectation *shouldResetIdentityExpectation = + [self expectationWithDescription:@"When server returns TOO_MANY_REGISTRATIONS, the client " + @"should report the failure reason."]; + int64_t tenHoursAgo = FIRMessagingCurrentTimestampInMilliseconds() - 10 * 60 * 60 * 1000; + FIRMessagingCheckinPreferences *checkinPreferences = + [self setCheckinPreferencesWithLastCheckinTime:tenHoursAgo]; + + FIRMessagingTokenFetchOperation *operation = [[FIRMessagingTokenFetchOperation alloc] + initWithAuthorizedEntity:kAuthorizedEntity + scope:kScope + options:nil + checkinPreferences:checkinPreferences + instanceID:self.instanceID + heartbeatLogger:[[FIRHeartbeatLoggerFake alloc] init]]; + NSURL *expectedRequestURL = [NSURL URLWithString:FIRMessagingTokenRegisterServer()]; + NSHTTPURLResponse *expectedResponse = [[NSHTTPURLResponse alloc] initWithURL:expectedRequestURL + statusCode:200 + HTTPVersion:@"HTTP/1.1" + headerFields:nil]; + + [FIRURLSessionOCMockStub + stubURLSessionDataTaskWithResponse:expectedResponse + body:[self dataForResponseWithValidToken: + @"TOO_MANY_REGISTRATIONS"] + error:nil + URLSessionMock:self.URLSessionMock + requestValidationBlock:^BOOL(NSURLRequest *_Nonnull sentRequest) { + return YES; + }]; + + [operation addCompletionHandler:^(FIRMessagingTokenOperationResult result, + NSString *_Nullable token, NSError *_Nullable error) { + XCTAssertEqual(result, FIRMessagingTokenOperationError); + XCTAssertNotNil(error); + XCTAssertEqual(error.code, kFIRMessagingErrorCodeUnknown); + XCTAssertEqualObjects(error.localizedFailureReason, @"TOO_MANY_REGISTRATIONS"); + + [shouldResetIdentityExpectation fulfill]; + }]; + + [operation start]; + + [self waitForExpectationsWithTimeout:0.25 + handler:^(NSError *_Nullable error) { + XCTAssertNil(error.localizedDescription); + }]; +} + - (void)testHTTPAuthHeaderGenerationFromCheckin { FIRMessagingCheckinPreferences *checkinPreferences = [[FIRMessagingCheckinPreferences alloc] initWithDeviceID:kDeviceID secretToken:kSecretToken]; @@ -447,7 +496,7 @@ - (void)assertTokenFetchOperationRequestContainsFirebaseUserAgentAndHeartbeatInf [FIRURLSessionOCMockStub stubURLSessionDataTaskWithResponse:expectedResponse - body:[self dataForResponseWithValidToken:NO] + body:[self dataForResponseWithValidToken:@"RST"] error:nil URLSessionMock:self.URLSessionMock requestValidationBlock:^BOOL(NSURLRequest *_Nonnull sentRequest) { @@ -471,12 +520,12 @@ - (void)assertTokenFetchOperationRequestContainsFirebaseUserAgentAndHeartbeatInf }]; } -- (NSData *)dataForResponseWithValidToken:(BOOL)validToken { +- (NSData *)dataForResponseWithValidToken:(NSString *)errorCode { NSString *response; - if (validToken) { + if (errorCode.length == 0) { response = [NSString stringWithFormat:@"token=%@", kRegistrationToken]; } else { - response = @"Error=RST"; + response = [NSString stringWithFormat:@"Error=%@", errorCode]; } return [response dataUsingEncoding:NSUTF8StringEncoding]; }