• Stars
    star
    120
  • Rank 295,983 (Top 6 %)
  • Language
    Swift
  • License
    MIT License
  • Created over 6 years ago
  • Updated 5 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

⚡️ PushNotifications through FireBase for Vapor 3 and 4.

Mihael Isaev

MIT License Swift 5.2 Swift.Stream


Intro 👏

It's a swift lib that gives ability to send push notifications through Firebase Cloud Messaging.

Built for Vapor4 and depends on JWT Vapor lib.

💡Vapor3 version is available in vapor3 branch and from 1.0.0 tag

If you have great ideas of how to improve this package write me (@iMike#3049) in Vapor's discord chat or just send pull request.

Hope it'll be useful for someone :)

Install through Swift Package Manager ❤️

Edit your Package.swift

//add this repo to dependencies
.package(url: "https://github.com/MihaelIsaev/FCM.git", from: "2.7.0")
//and don't forget about targets
.product(name: "FCM", package: "FCM")

How it works ?

First of all you should configure FCM in configure.swift

import FCM

// Called before your application initializes.
func configure(_ app: Application) throws {
    /// case 1
    /// with service account json file
    /// put into your environment variables the following key:
    /// FCM_SERVICE_ACCOUNT_KEY_PATH=path/to/serviceAccountKey.json
    app.fcm.configuration = .envServiceAccountKey
    
    /// case 2
    /// with service account json string
    /// put into your environment variable the following key:
    /// FCM_SERVICE_ACCOUNT_KEY="{"prohect_id": "my_project123",...}"
    app.fcm.configuration = .envServiceAccountKey
    
    /// case 3
    /// put into your environment variables the following keys:
    /// FCM_EMAIL=...          // `client_email` in service.json
    /// FCM_PROJECT_ID=...     // `project_id` in service.json
    /// FCM_PRIVATE_KEY=...    // `private_key` in service.json
    app.fcm.configuration = .envServiceAccountKeyFields

    /// case 4
    /// put into your environment variables the following keys:
    /// FCM_EMAIL=...
    /// FCM_PROJECT_ID=...
    /// FCM_KEY_PATH=path/to/key.pem
    app.fcm.configuration = .envCredentials

    /// case 5
    /// manually
    app.fcm.configuration = .init(email: "...", projectId: "...", key: "...")
}

⚠️ TIP: serviceAccountKey.json you could get from Firebase Console

🔑 Just go to Settings -> Service Accounts tab and press Create Private Key button in e.g. NodeJS tab

OPTIONAL: Set default configurations, e.g. to enable notification sound

Add the following code to your configure.swift after app.fcm.configuration = ...

app.fcm.configuration?.apnsDefaultConfig = FCMApnsConfig(headers: [:], 
                                                         aps: FCMApnsApsObject(sound: "default"))

app.fcm.configuration?.androidDefaultConfig = FCMAndroidConfig(ttl: "86400s",
                                                               restricted_package_name: "com.example.myapp",
                                                               notification: FCMAndroidNotification(sound: "default"))
                                                
app.fcm.configuration?.webpushDefaultConfig = FCMWebpushConfig(headers: [:],
                                                               data: [:],
                                                               notification: [:])

Let's send first push notification! 🚀

Then you could send push notifications using token, topic or condition.

Here's an example route handler with push notification sending using token

import FCM

func routes(_ app: Application) throws {
    app.get("testfcm") { req -> EventLoopFuture<String> in
        let token = "<YOUR FIREBASE DEVICE TOKEN>" // get it from iOS/Android SDK
        let notification = FCMNotification(title: "Vapor is awesome!", body: "Swift one love! ❤️")
        let message = FCMMessage(token: token, notification: notification)
        return req.fcm.send(message, on: req.eventLoop).map { name in
            return "Just sent: \(name)"
        }
    }
}

fcm.send returns message name like projects/example-3ab5c/messages/1531222329648135

FCMMessage struct is absolutely the same as Message struct in Firebase docs https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages So you could take a look on its source code to build proper message.

Batch sending

Preparation

  1. Go to Firebase Console -> Project Settings -> Cloud Messaging tab
  2. Copy Server Key from Project Credentials area
  3. Put server key into environment variables as FCM_SERVER_KEY=<YOUR_SERVER_KEY> (or put it into serviceAccountKey.json file as server_key)

Sending

// get it from iOS/Android SDK
let token1 = "<YOUR FIREBASE DEVICE TOKEN>"
let token2 = "<YOUR FIREBASE DEVICE TOKEN>"
let token3 = "<YOUR FIREBASE DEVICE TOKEN>"
...
let token100500 = "<YOUR FIREBASE DEVICE TOKEN>"

let notification = FCMNotification(title: "Life is great! 😃", body: "Swift one love! ❤️")
let message = FCMMessage(notification: notification)
application.fcm.batchSend(message, tokens: [token1, token2, token3, ..., token100500]).map {
    print("sent!")
}

APNS to Firebase token conversion

You can throw away Firebase libs from dependencies of your iOS apps because you can send pure APNS tokens to your server and it will register it in Firebase by itself.

It is must have for developers who don't want to add Firebase libs into their apps, and especially for iOS projects who use Swift Package Manager cause Firebase doesn't have SPM support for its libs yet.

How to use

Preparation

  1. Go to Firebase Console -> Project Settings -> Cloud Messaging tab
  2. Copy Server Key from Project Credentials area

Next steps are optional

  1. Put server key into environment variables as FCM_SERVER_KEY=<YOUR_SERVER_KEY> (or put it into serviceAccountKey.json file as server_key)
  2. Put your app bundle identifier into environment variables as FCM_APP_BUNDLE_ID=<APP_BUNDLE_ID>

Tokens registration

/// The simplest way
/// .env here means that FCM_SERVER_KEY and FCM_APP_BUNDLE_ID will be used
application.fcm.registerAPNS(.env, tokens: "token1", "token3", ..., "token100").flatMap { tokens in
    /// `tokens` is array of `APNSToFirebaseToken` structs
    /// which contains:
    /// registration_token - Firebase token
    /// apns_token - APNS token
    /// isRegistered - boolean value which indicates if registration was successful
}

/// instead of .env you could declare your own identifier
extension RegisterAPNSID {
   static var myApp: RegisterAPNSID { .init(appBundleId: "com.myapp") }
}

/// Advanced way
application.fcm.registerAPNS(
    appBundleId: String, // iOS app bundle identifier
    serverKey: String?, // optional server key, if nil then env variable will be used
    sandbox: Bool, // optional sandbox key, false by default
    tokens: [String], // an array of APNS tokens
    on: EventLoop? // optional event loop, if nil then application.eventLoopGroup.next() will be used
).flatMap { tokens in
    /// the same as in above example
}

💡 Please note that push token taken from Xcode while debugging is for sandbox, so either use .envSandbox or don't forget to set sandbox: true

Contributors

Special thanks to @grahamburgsma for GoogleError and FCMError #10

More Repositories

1

UIKitPlus

🏰 Declarative UIKit with LivePreview for iOS9+ (best alternative to SwiftUI)
Swift
593
star
2

FluentQuery

🗃 Powerful and easy to use Swift Query Builder for Vapor 3.
Swift
148
star
3

VaporCron

⏲ Swift cron scheduler for Vapor
Swift
85
star
4

AwesomeWS

🍬 An elegant way to use websockets with Vapor
Swift
44
star
5

wkhtmltopdf

📖 PDF render for Swift and Vapor 3.
Swift
38
star
6

SwiftPopTipView

💬 Popups for iOS
Swift
37
star
7

SwifCron

⏱Simple pure swift cron expression parser
Swift
29
star
8

NIOCronScheduler

⌚️Swift cron scheduler based on Swift NIO (both v1 and v2)
Swift
24
star
9

UIKitPlusExample

An example project for UIKitPlus library 👏
Swift
24
star
10

BeautifulButtons

❤️ iOS5 beautiful buttons
Objective-C
21
star
11

SwifRootViewController

🍀Useful root navigation view controller (by best practice)
Swift
15
star
12

Localizer

🇮🇸🇩🇪🇯🇵🇲🇽 Swift localization helper
Swift
14
star
13

MultiSelectSegmentedControl

A swift representation of yonat/MultiSelectSegmentedControl
Swift
12
star
14

MaskedEditTextWatcher

Custom TextWatcher for EditText to mask phone number on-the-fly even with automatic country mask detection
Java
11
star
15

ECSwiftSlidingViewController

Translated to Swift ECSlidingViewController
Swift
10
star
16

Vaporizer

✈️ Vapor 4 declarative wrapper
Swift
8
star
17

State

Swift @State
Swift
7
star
18

AlexoChat

A simple realtime chat written in Swift on Vapor 3
Swift
7
star
19

ChatInMacOSX

Chat for inmac.org
Objective-C
7
star
20

braintree_swift

💰Not official Swift Braintree provider for Vapor 3
Swift
7
star
21

branch.io.spm

Branch.io iOS SDK with SPM support (cleaned from `framework` files)
Objective-C
4
star
22

RealmQuantityGetterBug

This project reproduce Realm getter/setter glitch
Objective-C
2
star
23

SwifQLNIO

Helper library for SwifQL and SwiftNIO
Swift
2
star
24

SignalAppUIKitPlus

Demo application for UIKitPlus
Swift
2
star
25

VaporAvtokod

Avtokod.ru provider for Vapor 3
Swift
2
star
26

Branch

Branch.io API wrapper for Vapor4
Swift
2
star
27

VKPlayer

Music player for vk.com
Objective-C
1
star
28

MihaelIsaev

1
star
29

VaporDocs

An alternative documentation 🙂
1
star
30

SimpleStreamVideoPlayer

Swift
1
star
31

pwa.github.io

HTML
1
star
32

VaporAutostat

Server-side Swift library for autostat.ru https://www.autostat.ru/help/pricecalc/
Swift
1
star
33

BridgesSubqueryArrayExample

1
star
34

CoreDataTempContext

The swift class to get the temp copy of current NSManagedObjectContext, use it and merge it
1
star