简体   繁体   中英

Firestore Messaging: Sending message to Topic with Swift

I'm converting my iOS app over from CloudKit to Firestore. So far everything is working great except for notifications. I have users subscribed to specific topics which works great if I use the website to send a message.

However, I need my iOS app to send a message and google provides amazing documentation on how to do that. Their instructions are

(Send to a single Topic)
POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1

Content-Type: application/json
Authorization: Bearer (Server Key)
{
  "message":{
    "topic" : "foo-bar",
    "notification" : {
      "body" : "This is a Firebase Cloud Messaging Topic Message!",
      "title" : "FCM Message"
      }
   }
}

So in order to do that, I decided to use an http request to post that information. Here's my code...

let json: [String: Any] = ["message": ["topic":"\(Items.sharedInstance.clubSelected2.id)", "notification":["body":"Test Body","title":"Test Title"]]]
let jsonData = try? JSONSerialization.data(withJSONObject: json)

let url = URL(string: "https://fcm.googleapis.com/v1/projects/(My Project)/messages:send")!
var request = URLRequest(url: url)

request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("Bearer (My Server Key)", forHTTPHeaderField: "Authorization")
request.httpMethod = "POST"
request.httpBody = jsonData

let task = URLSession.shared.dataTask(with: request) { data, response, error in
    guard let data = data, error == nil else {
        // check for fundamental networking error
        print("error=\(error)")
        return
    }

    if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {           // check for http errors
        print("statusCode should be 200, but is \(httpStatus.statusCode)")
        print("response = \(response)")
    }

    let responseString = String(data: data, encoding: .utf8)
        print("responseString = \(responseString)")
    }
    task.resume()

With all of this, I get the error "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project .\\". I have created new server keys and still get the same error. The following is what I have tried for the Authorization field... without the parenthesis of course

  • Bearer (Server Key)
  • Bearer (New Server Key)
  • Bearer (Legacy Server Key)
  • key=(Server Key)
  • key=(New Server Key)
  • key=(Legacy Server Key)

Any help in what could fix this authorization error would be greatly appreciated!

FCM v1 does not send messages from the client, only from a server. You need to use XMPP to send outgoing messages directly from the client. Personally, I'd prefer to send from a server. You could send an outgoing request to your server to handle the message, or trigger a Cloud Function to run automatically.

If you want to use FCM v1, the latest version of FCM, you'll need to send from a server instead. Firebase offers Admin SDKs , which enable you to access Firebase products server-side. Then you don't have to handle generating credentials or building the request.

When using the FCM v1 endpoint through a POST request instead of through the Admin SDK, credentials for FCM v1 are generated using the Service Account Key JSON file. See instructions in the guide . You can download the file from the Firebase console here . Select your project to go to the location in the dashboard. Included in the guide is the code for getting the credentials from the file.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM