I'm currently working on an iOS app (using Swift) that sends push notifications between two users when any of them sends a message to the other (and when other events happen as well). For that, I'm using Firebase Cloud Messaging and this is the swift function that actually sends the notification:
let accessToken = "xxxx"
let urlString = "https://fcm.googleapis.com/v1/projects/\( K.FCMessaging.projectId)/messages:send"
let url = NSURL(string: urlString)!
let paramString: [String : Any] = ["message": [
"apns" : ["payload" : ["aps": ["alert": ["title": title, "body": body], "sound": "default"] as [String : Any], OrderModel.CodingKeys.orderId.rawValue: order.orderId!, OrderModel.CodingKeys.senderId.rawValue: order.senderId] as [String : Any]],
"token" : receiverToken] as [String : Any]
]
let request = NSMutableURLRequest(url: url as URL)
request.httpMethod = "POST"
request.httpBody = try? JSONSerialization.data(withJSONObject:paramString)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")
let task = URLSession.shared.dataTask(with: request as URLRequest)
task.resume()
The access token is obtained by running this python code locally on the Mac:
import argparse
import json
import requests
import google.auth.transport.requests
from google.oauth2 import service_account
PROJECT_ID = 'xxxx'
BASE_URL = 'https://fcm.googleapis.com'
FCM_ENDPOINT = 'v1/projects/' + PROJECT_ID + '/messages:send'
FCM_URL = BASE_URL + '/' + FCM_ENDPOINT
SCOPES = ['https://www.googleapis.com/auth/firebase.messaging']
def access_token():
credentials = service_account.Credentials.from_service_account_file('/Users/...-firebase-xxxx.json', scopes=SCOPES)
request = google.auth.transport.requests.Request()
credentials.refresh(request)
return credentials.token
Now everything works fine (i.e. the notifications get sent and received) when I copy the access token into the swift function, but it expires after one hour and I have to run the code again and copy the access token again. Since I don't have a server to automatically run the python function on, it seems like I'm missing something. Can you please tell me how to get a permanent access token for the app or the right way of sending push notifications between two devices in iOS?
Short answer is: No, not with FCM v1.
Since Google transitioned to FCM v1, they now mandate the use of OAuth2, unlike FCM (legacy). OAuth2 functions by generating temporary tokens, which serve as a preventive measure against various attacks, such as man-in-the-middle attacks. Consequently, the use of a permanent code is unfortunately not possible.
As mentioned in the comments, the most straightforward approach in my opinion is to leverage Google Cloud Functions. This approach minimizes the workload for your local app. However, it’s unfortunate that you don’t have access in your country.