GCM notifications are not accepted when the application is in the background in iOS

I have configured GCM in my existing application and I get notifications there. Now I am faced with two problems: 1) I do not receive a notification. When I exit the application or application in the background. 2) I do not receive notification in the iphone notification area, only when my application is running, I receive only a direct warning message. And when I pull out the notification area, I get this message in the xcode console "Failed to connect to GCM: operation could not be completed (error com.google.gcm 2001.)"

My PHP file is below

<?php // Payload data you want to send to iOSdevice(s) // (it will be accessible via intent extras) $data = array( 'message' => 'Hello World!'); // The recipient registration tokens for this notification // http://developer.android.com/google/gcm/ $ids = array( 'kucy6xoUmx********eeRsla' ); // Send a GCM push sendGoogleCloudMessage( $data, $ids ); function sendGoogleCloudMessage( $data, $ids ) { // Insert real GCM API key from Google APIs Console // https://code.google.com/apis/console/ $apiKey = 'AIz******9JA'; // Define URL to GCM endpoint $url = 'https://gcm-http.googleapis.com/gcm/send'; // Set GCM post variables (device IDs and push payload) $post = array( 'registration_ids' => $ids, 'data' => $data, ); // Set CURL request headers (authentication and type) $headers = array( 'Authorization: key=' . $apiKey, 'Content-Type: application/json' ); // Initialize curl handle $ch = curl_init(); // Set URL to GCM endpoint curl_setopt( $ch, CURLOPT_URL, $url ); // Set request method to POST curl_setopt( $ch, CURLOPT_POST, true ); // Set our custom headers curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers ); // Get the response back as string instead of printing it curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); // Set JSON post data curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode( $post ) ); // Actually send the push $result = curl_exec( $ch ); // Error handling if ( curl_errno( $ch ) ) { echo 'GCM error: ' . curl_error( $ch ); } // Close curl handle curl_close( $ch ); // Debug GCM response echo $result; } ?> 

Here is my AppDelegate.m file

 // [START register_for_remote_notifications] - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // [START_EXCLUDE] _registrationKey = @"onRegistrationCompleted"; _messageKey = @"onMessageReceived"; // Configure the Google context: parses the GoogleService-Info.plist, and initializes // the services that have entries in the file NSError* configureError; [[GGLContext sharedInstance] configureWithError:&configureError]; NSAssert(!configureError, @"Error configuring Google services: %@", configureError); _gcmSenderID = [[[GGLContext sharedInstance] configuration] gcmSenderID]; // Register for remote notifications if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1) { // iOS 7.1 or earlier UIRemoteNotificationType allNotificationTypes = (UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge); [application registerForRemoteNotificationTypes:allNotificationTypes]; } else { // iOS 8 or later // [END_EXCLUDE] UIUserNotificationType allNotificationTypes = (UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge); UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:nil]; [[UIApplication sharedApplication] registerUserNotificationSettings:settings]; [[UIApplication sharedApplication] registerForRemoteNotifications]; } // [END register_for_remote_notifications] // [START start_gcm_service] GCMConfig *gcmConfig = [GCMConfig defaultConfig]; gcmConfig.receiverDelegate = self; [[GCMService sharedInstance] startWithConfig:gcmConfig]; // [END start_gcm_service] __weak typeof(self) weakSelf = self; // Handler for registration token request _registrationHandler = ^(NSString *registrationToken, NSError *error){ if (registrationToken != nil) { weakSelf.registrationToken = registrationToken; NSLog(@"Registration Token: %@", registrationToken); [weakSelf subscribeToTopic]; NSDictionary *userInfo = @{@"registrationToken":registrationToken}; [[NSNotificationCenter defaultCenter] postNotificationName:weakSelf.registrationKey object:nil userInfo:userInfo]; } else { NSLog(@"Registration to GCM failed with error: %@", error.localizedDescription); NSDictionary *userInfo = @{@"error":error.localizedDescription}; [[NSNotificationCenter defaultCenter] postNotificationName:weakSelf.registrationKey object:nil userInfo:userInfo]; } }; return YES; } - (void)subscribeToTopic { // If the app has a registration token and is connected to GCM, proceed to subscribe to the // topic if (_registrationToken && _connectedToGCM) { [[GCMPubSub sharedInstance] subscribeWithToken:_registrationToken topic:SubscriptionTopic options:nil handler:^(NSError *error) { if (error) { // Treat the "already subscribed" error more gently if (error.code == 3001) { NSLog(@"Already subscribed to %@", SubscriptionTopic); } else { NSLog(@"Subscription failed: %@", error.localizedDescription); } } else { self.subscribedToTopic = true; NSLog(@"Subscribed to %@", SubscriptionTopic); } }]; } } // [START connect_gcm_service] - (void)applicationDidBecomeActive:(UIApplication *)application { // Connect to the GCM server to receive non-APNS notifications [[GCMService sharedInstance] connectWithHandler:^(NSError *error) { if (error) { NSLog(@"Could not connect to GCM: %@", error.localizedDescription); } else { _connectedToGCM = true; NSLog(@"Connected to GCM"); // [START_EXCLUDE] [self subscribeToTopic]; // [END_EXCLUDE] } }]; } // [END connect_gcm_service] // [START disconnect_gcm_service] - (void)applicationDidEnterBackground:(UIApplication *)application { [[GCMService sharedInstance] disconnect]; // [START_EXCLUDE] _connectedToGCM = NO; // [END_EXCLUDE] } // [END disconnect_gcm_service] // [START receive_apns_token] - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { // [END receive_apns_token] // [START get_gcm_reg_token] // Create a config and set a delegate that implements the GGLInstaceIDDelegate protocol. GGLInstanceIDConfig *instanceIDConfig = [GGLInstanceIDConfig defaultConfig]; instanceIDConfig.delegate = self; // Start the GGLInstanceID shared instance with the that config and request a registration // token to enable reception of notifications [[GGLInstanceID sharedInstance] startWithConfig:instanceIDConfig]; _registrationOptions = @{kGGLInstanceIDRegisterAPNSOption:deviceToken, kGGLInstanceIDAPNSServerTypeSandboxOption:@"NO"}; [[GGLInstanceID sharedInstance] tokenWithAuthorizedEntity:_gcmSenderID scope:kGGLInstanceIDScopeGCM options:_registrationOptions handler:_registrationHandler]; // [END get_gcm_reg_token] } // [START receive_apns_token_error] - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { NSLog(@"Registration for remote notification failed with error: %@", error.localizedDescription); // [END receive_apns_token_error] NSDictionary *userInfo = @{@"error" :error.localizedDescription}; [[NSNotificationCenter defaultCenter] postNotificationName:_registrationKey object:nil userInfo:userInfo]; } // [START ack_message_reception] - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { NSLog(@"Notification received: %@", userInfo); // This works only if the app started the GCM service [[GCMService sharedInstance] appDidReceiveMessage:userInfo]; // Handle the received message // [START_EXCLUDE] [[NSNotificationCenter defaultCenter] postNotificationName:_messageKey object:nil userInfo:userInfo]; // [END_EXCLUDE] } - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))handler { NSLog(@"Notification received: %@", userInfo); // This works only if the app started the GCM service [[GCMService sharedInstance] appDidReceiveMessage:userInfo]; // Handle the received message // Invoke the completion handler passing the appropriate UIBackgroundFetchResult value // [START_EXCLUDE] [[NSNotificationCenter defaultCenter] postNotificationName:_messageKey object:nil userInfo:userInfo]; handler(UIBackgroundFetchResultNoData); // [END_EXCLUDE] } // [END ack_message_reception] // [START on_token_refresh] - (void)onTokenRefresh { // A rotation of the registration tokens is happening, so the app needs to request a new token. NSLog(@"The GCM registration token needs to be changed."); [[GGLInstanceID sharedInstance] tokenWithAuthorizedEntity:_gcmSenderID scope:kGGLInstanceIDScopeGCM options:_registrationOptions handler:_registrationHandler]; } // [END on_token_refresh] // [START upstream_callbacks] - (void)willSendDataMessageWithID:(NSString *)messageID error:(NSError *)error { if (error) { // Failed to send the message. } else { // Will send message, you can save the messageID to track the message } } - (void)didSendDataMessageWithID:(NSString *)messageID { // Did successfully send message identified by messageID } // [END upstream_callbacks] - (void)didDeleteMessagesOnServer { // Some messages sent to this device were deleted on the GCM server before reception, likely // because the TTL expired. The client should notify the app server of this, so that the app // server can resend those messages. } 

I am not a php script master, so please help me how can I solve my problems.

+3
source share
2 answers

I added

  'content_available' => true,//to trigger when iOS app is in background 'priority' => 'high', 'notification' => $data, $data = array( 'message' => 'Hello World!', 'body' => 'Hello World!'); 

to your code. Please try below code;

 <?php // Payload data you want to send to iOSdevice(s) // (it will be accessible via intent extras) $data = array( 'message' => 'Hello World!', 'body' => 'Hello World!'); // The recipient registration tokens for this notification // http://developer.android.com/google/gcm/ $ids = array( 'kucy6xoUmx********eeRsla' ); // Send a GCM push sendGoogleCloudMessage( $data, $ids ); function sendGoogleCloudMessage( $data, $ids ) { // Insert real GCM API key from Google APIs Console // https://code.google.com/apis/console/ $apiKey = 'AIz******9JA'; // Define URL to GCM endpoint $url = 'https://gcm-http.googleapis.com/gcm/send'; // Set GCM post variables (device IDs and push payload) $post = array( 'registration_ids' => $ids, 'data' => $data, 'content_available' => true, 'priority' => 'high', 'notification' => $data, ); // Set CURL request headers (authentication and type) $headers = array( 'Authorization: key=' . $apiKey, 'Content-Type: application/json' ); // Initialize curl handle $ch = curl_init(); // Set URL to GCM endpoint curl_setopt( $ch, CURLOPT_URL, $url ); // Set request method to POST curl_setopt( $ch, CURLOPT_POST, true ); // Set our custom headers curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers ); // Get the response back as string instead of printing it curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); // Set JSON post data curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode( $post ) ); // Actually send the push $result = curl_exec( $ch ); // Error handling if ( curl_errno( $ch ) ) { echo 'GCM error: ' . curl_error( $ch ); } // Close curl handle curl_close( $ch ); // Debug GCM response echo $result; } ?> 

on the side of iOS; Fill Orders on the GCM Website

EDIT 1: You can try sending a notification to ios;

I edited your php code above; Changes:

'notification' => $ data,

and

$ data = array ('message' => 'Hello World!', 'body' => 'Hello World!');

+4
source

GCM receives notification in invalid state 2.

Developers who use the GCM integration for Android and iOS must add certain things to their email call to the GCM server. For iOS: We need two additional things to do the same call job in iOS: 'notification' => $ data, 'content_available' => 'true',

Apple push notification service requires content_available to be true. And then the data "notification" => $ helps the Notification Center to know that the notification has arrived and you need to click on the device.

+1
source

Source: https://habr.com/ru/post/1240541/


All Articles