"iOS users have reported that notifications from Firebase have mysteriously ceased to

Yesterday evening, I was experimenting with Push Notifications from Firebase on my iOS application and everything was functioning correctly.

I successfully sent a notification from a Cloud Function to a specific FCM token. However, this morning, notifications are not being received using the same process.

Cloud Function

Below is the function I am using to send the notification:

function sendNotification(title: string, body: string, token: string): Promise<void> {
    const message: admin.messaging.Message = {
        apns: {
            headers: {
                'apns-priority': '10'
            },
            payload: {
                aps: {
                    alert: {
                        title: title,
                        body: body,
                    },
                    sound: "default"
                }
            }
        },
        token: token
    }
    return admin.messaging().send(message).then(response => { console.log(`Notification response ${response}`) }).then(justVoid)
}

The `token` mentioned above is the token obtained from the InstanceId in the iOS app. After triggering this function, the Cloud Function log in the Firebase web console shows the following message:

Notification response projects/project-name/messages/0:1571998931167276%0f7d46fcf9fd7ecd

This appears to be a success message. However, despite this, the notification does not appear on the device.

iOS App

I have followed this troubleshooting guide and confirmed that the setup is correct: https://firebase.google.com/docs/cloud-messaging/ios/first-message?authuser=0

In an attempt to resolve the issue, I re-installed the app on the testing device and ensured that the following steps were completed after re-installation:

  • Call:

    UNUserNotificationCenter.current().requestAuthorization(options:, completionHandler:)

  • Call:

    UIApplication.shared.registerForRemoteNotifications()

  • Listen for updated FCM token by implementing:

    func messaging(_ messaging:, didReceiveRegistrationToken fcmToken:)

  • Call:

    InstanceID.instanceID().instanceID(handler:)

  • Double check that notifications are allowed for my application in the iOS settings app.

Test Notification from Console

I attempted to send a Test Notification from the Notification Composer, using the most recent FCM token for the test device. Unfortunately, this notification also failed to appear, and there was no visible feedback indicating whether it was successfully sent or not.

What could be causing this issue?

Any recommendations on how to troubleshoot and debug this problem?

Answer №1

It can be quite challenging to troubleshoot issues when dealing with Push Notifications.

In my own experience, it seems that there is nothing wrong with your typescript or iOS code since it was functioning correctly before. The issue with push notifications not working could potentially be related to the APNS certificate.

Here are some possible reasons why push notifications may not be working:

  • Ensure you have uploaded the correct APNS profile to the Firebase console for both development and release modes.

  • Verify that notifications are enabled in capabilities settings.

    Your Project -> capabilities -> turn on Push Notifications

  • Make sure the correct GoogleService-Info.plist file has been added to the project.

  • Check that the APNS Certificate has not expired.

  • Ensure you are using the latest version of Firebase.

  • Set your device time to automatic, not manual.

If you still suspect a code-related issue and the above solutions do not work, you can try using the following wrapper class of HSAPNSHelper, which I have created and confirmed to work for iOS 10 and later.

import Foundation
import UserNotifications
import Firebase

class HSAPNSHelper: NSObject {

    static let shared = HSAPNSHelper()
    let local_fcm_token = "local_fcm_token"

    var notificationID = ""

    func registerForPushNotification(application:UIApplication){

        FirebaseApp.configure()

        self.getFCMToken()
        UNUserNotificationCenter.current().delegate = self
        UNUserNotificationCenter.current().requestAuthorization(options: [.badge, .alert, .sound]) { (granted, error) in
            DispatchQueue.main.async {
                self.getFCMToken()
            }
        }
        application.registerForRemoteNotifications()
    }
}


extension HSAPNSHelper:UNUserNotificationCenterDelegate {

    fileprivate func getFCMToken() {
        InstanceID.instanceID().instanceID(handler: { (result, error) in
            if error == nil, let fcmToken = result?.token{
                print("FCM Token HS: \(fcmToken)")
                UserDefaults.standard.set(fcmToken, forKey: self.local_fcm_token)
            }
        })
    }

    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        print("didFailToRegisterForRemoteNotificationsWithError : \(error)")
    }

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {

        var token = ""
        for i in 0..<deviceToken.count {
            token = token + String(format: "%02.2hhx", arguments: [deviceToken[i]])
        }
        Messaging.messaging().apnsToken = deviceToken
        getFCMToken()
    }

    @available(iOS 10.0, *)
    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                willPresent notification: UNNotification,
                                withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {

        let userInfo = notification.request.content.userInfo as! [String: Any]
        print(userInfo)
        completionHandler([.alert, .badge, .sound])
    }

    @available(iOS 10.0, *)
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        let userInfo = response.notification.request.content.userInfo
        print(userInfo)
        self.notificationRedirection()
    }

    private func notificationRedirection(){

    }

    func fcmToken() -> String{
        return UserDefaults.standard.string(forKey:local_fcm_token) ?? ""
    }
}

How to implement?

  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        //For implementing Push Notification
        HSAPNSHelper.shared.registerForPushNotification(application: application)
        return true;
    }

Use fcmToken() to retrieve the current FCM token.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The letter 'X' is not suitable for use as a JSX component because its return type 'Element[]' does not qualify as a valid JSX element

Currently, I am working on rendering two simple joke cards in TypeScript. The cards are displaying correctly in my browser, but I've encountered an error message that says: 'Jokes' cannot be used as a JSX component. Its return type 'Ele ...

Convert the Date FR and Date US formats to ISO date format

There is a function in my code that accepts dates in different formats. It can handle two formats: 2022-06-04 or 04/06/2022 I want all dates to be in the format: 2022-06-04 For instance: public getMaxduration(data: object[]): number { data.forEach((l ...

Attempting to construct a MultiPart entity in Java using a multipart form data created from Objective-C code

I have taken on the task of converting an iOS app to android, but I am struggling with understanding the multipart entity that is used in the original code. NSMutableData *body = [NSMutableData data]; // file NSData *imageData = UIImageJPEGRepres ...

`Creating a union of prop types in TypeScript and React`

I'm facing an issue with a component prop that I need to restrict to specific strings using a union type, as shown below: type HeadingProps = { level?: 'h1' | 'h2' | 'h3' | 'h4'| 'h5' | 'h6&a ...

The scale line on the OpenLayers map displays the same metrics twice, even when the zoom level is different

When using the Openlayers Map scale line in Metric units, a specific zoom rate may be repeated twice during the zoom event, even though the actual zoom-in resolution varies on the map. In the provided link, you can observe that the zoom rates of 5km and ...

"Utilize TypeScript to create a function that can handle either a single value or

I am attempting to develop a double function with the following structure: type MaybeArray<T> = T | T[]; function double<T extends MaybeArray<number>>(data: T): T extends number[] ? number[] : number { if (Array.isArray(data)) { / ...

Angular Inner Class

As a newcomer to Angular, I have a question about creating nested classes in Angular similar to the .NET class structure. public class BaseResponse<T> { public T Data { get; set; } public int StatusCo ...

Achieving intellisense functionality in TypeScript without the use of classes

Just dipped my toes into TypeScript, attempting to convert this basic JavaScript code to TypeScript. Here is the JavaScript code snippet: Item = {} Item.buy = function (id) {} Item.sell = function (id) {} I prefer not to use classes and would like to ut ...

What is the best way to create a time-sensitive URL that automatically expires in 30 minutes?

I have a unique project requirement where I need to generate a URL for each user that expires after 30 minutes. For every user, there is a distinct UUID. Upon clicking the generated URL, it should trigger a cloud function on Google Cloud to fetch data from ...

How to Retrieve the Current Item in *ngFor Loop Using TypeScript in Angular 4

In my JSON file, I have an array containing 5 people. Each person in the array has a list of items associated with them. In my HTML code, I am using *ngFor to iterate over the people and display their names. Additionally, I want to display the total sum of ...

What is the best way to eliminate a particular element from an array produced using the .map() function in

I am experiencing an issue with my EventCell.tsx component. When a user clicks on the component, an event is created by adding an element to the components state. Subsequently, a list of Event.tsx components is rendered using the .map() method. The problem ...

Adding an object with a composite key to an IndexedDB object store is not permitted as the key already exists within the store. This limitation occurs when attempting to add an entry

I am facing an issue with my objectStore where adding an object with the same productId but a different shopName triggers an error in the transaction showing: ConstraintError: Key already exists in the object store.. This is how I initialized the objectSto ...

Apply CSS styles conditionally to an Angular component

Depending on the variable value, I want to change the style of the p-autocomplete component. A toggle input determines whether the variable is true or false. <div class="switch-inner"> <p [ngClass]="{'businessG': !toggle }" clas ...

The error message "InvalidPipeArgument: '[object Object]' for pipe 'AsyncPipe' in Angular 6 and Firebase" indicates a problem with the data being passed to the AsyncPipe in

**Error: InvalidPipeArgument: '[object Object]' for pipe 'AsyncPipe'. ** I am encountering a problem with unsubscribing from the observable. My Angular-cli version is 6.0.3 This is the HTML code in home.component.html <div class ...

Determining the type of index to use for an interface

Imagine having an interface called Animal, with some general properties, and then either be a cat or a dog with corresponding properties. interface Dog { dog: { sound: string; } } interface Cat { cat: { lives: number; } } type CatOrDog = Cat | D ...

Utilize Array.push to add 2 new rows to a table using Angular 4

I have two arrays that are almost identical, except for two items which are the fakeDates: this.prodotti.push({ idAgreement: this.idAgreement,landingStatus: this.landingStatus, landingType: this.landingType, startDate: this.startDate, expirationDate: thi ...

No results returned by Mongoose/MongoDB GeoJSON query

I have a Schema (Tour) which includes a GeoJSON Point type property called location. location: { type: { type: String, enum: ['Point'], required: true }, coordinates: { type: [Number], required: true ...

What steps do I need to take to watch a video that I have chosen from my Gallery?

I am facing a challenge with my two view controllers: the GetStartedViewController (root viewController) and TrimVideoViewController. After selecting a video using PHPicker in the root view controller, I am unable to play that video in the second view cont ...

Ways to stop the running NSTimer when a new one is activated

My goal is to toggle the visibility of a view by tapping on it using NSTimer. @interface @property (nonatomic, retain)NSTimer *timer; UIView *view; @implementation view.hidden=YES; - (void)handleTap:(UITapGestur ...

When utilizing an object as state in React, the `setState` function will only set

Currently, I am working on developing a React form that utilizes a custom Input component which I have created multiple times. The objective is to gather all the names and values from the form in the parent component: {inputName: value, inputName2: valu ...