iOS Tutorial FirebaseNotifications / Push Messages (server not required)

Status
Not open for further replies.
Updated tutorial: https://www.b4x.com/android/forum/threads/b4x-firebase-push-notifications-2023.148715/
The configuration steps are still relevant.


Firebase Notifications service makes it relatively easy to send push messages.

Integrating Firebase: https://www.b4x.com/android/forum/threads/firebase-integration.68623/

Push messages in iOS requires some configuration.


1. Create a new explicit (non-wildcard) App ID with the package name of the push app. For example anywheresoftware.b4i.push. Enable push notification service.
2. Create an Apple Push Notification SSL certificate. Use the same certSigningRequest.csr file that you previously created.
This can be done from App IDs - Choose the id - Edit.
SS-2016-07-04_17.19.12.png


I recommend using a Production SSL Certificate with a Distribution / Ad Hoc provision profile. This way you can use the same tokens during development and in production.

3. Create a provision file with the new App ID.

Update: It is simpler to use the new and recommended APN authentication keys: https://www.b4x.com/android/forum/t...on-keys-vs-authentication-certificates.126402

Old keys (works as well):
4. There should be a file named aps_*.cer in the keys folder. Now you should click on Tools - Build Server - Create Push Key - Firebase Service:

SS-2016-07-04_17.25.02.png


This will create a file named firebase_push.p12 in the keys folder. You need to upload it to Firebase console under Settings - CLOUD MESSAGING:

SS-2016-07-04_17.35.51.png

You only need to upload the production APN.

5. Download GoogleService-Info.plist and copy it to Files\Special folder.

Code

The code should be similar to:
B4X:
#Entitlement: <key>aps-environment</key><string>production</string>
'use the distribution certificate
#CertificateFile: ios_distribution.cer
'use the provision profile that goes with the explicit App Id
#ProvisionFile: Firebase.mobileprovision
Sub Process_Globals
   Public App As Application
   Public NavControl As NavigationController
   Private Page1 As Page
   Private analytics As FirebaseAnalytics
   Private fm As FirebaseMessaging
End Sub

Private Sub Application_Start (Nav As NavigationController)
   analytics.Initialize
   NavControl = Nav
   Page1.Initialize("Page1")
   Page1.Title = "Page 1"
   Page1.RootPanel.Color = Colors.White
   NavControl.ShowPage(Page1)
   App.RegisterUserNotifications(True, True, True)
   App.RegisterForRemoteNotifications
   fm.Initialize("fm")
End Sub

Private Sub fm_FCMConnected
   Log("FCMConnected")
   'here we can subscribe and unsubscribe from topics
   fm.SubscribeToTopic("ios_general") 'add ios_ prefix to all topics
End Sub

Private Sub Application_RemoteNotification (Message As Map, CompletionHandler As CompletionHandler)
   Log($"Message arrived: ${Message}"$)
   Msgbox(Message, "Push message!")
   CompletionHandler.Complete
End Sub

Private Sub Application_Active
   fm.FCMConnect 'should be called from Application_Active
End Sub

Private Sub Application_Background
   fm.FCMDisconnect 'should be called from Application_Background
End Sub

Sub Application_PushToken (Success As Boolean, Token() As Byte)
   Log($"PushToken: ${Success}"$)
   Log(LastException)
End Sub

Use the attached B4J (non-ui) program to send messages. It handles ios messages a bit differently. There is an assumption that all iOS topics start with ios_.
 

Attachments

  • SendingTool.zip
    1 KB · Views: 2,293
Last edited:

karyadi

Member
Licensed User
Longtime User
hi all,

i try using firebase notification, when i run B4J Sending tools, it's show this
Waiting for debugger to connect...
Program started.
<HTML>
<HEAD>
<TITLE>Unauthorized</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<H1>Unauthorized</H1>
<H2>Error 401</H2>
</BODY>
</HTML>
[jobname=fcm, success=false, username=
, password=, errormessage=Unauthorized, target=class b4j.example.main
, taskid=1, req=anywheresoftware.b4h.okhttp.OkHttpClientWrapper$OkHttpRequest@1dc4ec2, tag=java.lang.Object@133314b
, httputils2service=null]

what wrong?
i already change my API_KEY with using Web API Key that i got from console.firebase.google.com
Sub Process_Globals
Private const API_KEY As String = "AIzaSyBkR_qTtUkwnpLb4ONV1FwCPcvzHnnDzlk"
End Sub

Here is the code
B4X:
'Non-UI application (console / server application)
#Region  Project Attributes
    #CommandLineArgs:
    #MergeLibraries: True
#End Region

Sub Process_Globals
    Private const API_KEY As String = "AIzaSyBkR_qTtUkwnpLb4ONV1FwCPcvzHnnDzlk"
End Sub

Sub AppStart (Args() As String)
    SendMessage("ios_general", "title", "body")
    StartMessageLoop
End Sub

Private Sub SendMessage(Topic As String, Title As String, Body As String)
    Dim Job As HttpJob
    Job.Initialize("fcm", Me)
    Dim m As Map = CreateMap("to": $"/topics/${Topic}"$)
    Dim data As Map = CreateMap("title": Title, "body": Body)
    If Topic.StartsWith("ios_") Then
        Dim iosalert As Map =  CreateMap("title": Title, "body": Body, "sound": "default")
        m.Put("notification", iosalert)
        m.Put("priority", 10)
    End If
    m.Put("data", data)
    Dim jg As JSONGenerator
    jg.Initialize(m)
    Job.PostString("https://fcm.googleapis.com/fcm/send", jg.ToString)
    Job.GetRequest.SetContentType("application/json;charset=UTF-8")
    Job.GetRequest.SetHeader("Authorization", "key=" & API_KEY)
End Sub


Sub JobDone(job As HttpJob)
   Log(job)
   If job.Success Then
     Log(job.GetString)
   End If
   job.Release
   ExitApplication '!
End Sub

Please help me

thanks
 

jazzzzzzz

Active Member
Licensed User
Longtime User
I have successfully setup every thing and push is receiving in my device.I used exactly the same code as in example so msgbox is coming.

But no notification is shown in my notification area in phone when app is in background..So how to show the message in notification area?
 

tufanv

Expert
Licensed User
Longtime User
I have successfully setup every thing and push is receiving in my device.I used exactly the same code as in example so msgbox is coming.

But no notification is shown in my notification area in phone when app is in background..So how to show the message in notification area?
1) check you have included :
B4X:
#Entitlement: <key>aps-environment</key><string>production</string>
2) check you have included :
B4X:
   App.RegisterUserNotifications(True, True, True)
   App.RegisterForRemoteNotifications
 

jazzzzzzz

Active Member
Licensed User
Longtime User
1) check you have included :
B4X:
#Entitlement: <key>aps-environment</key><string>production</string>
2) check you have included :
B4X:
   App.RegisterUserNotifications(True, True, True)
   App.RegisterForRemoteNotifications
both are there,but only msgbox is coming when app is active.No notification is coming after pressing home button
 

jazzzzzzz

Active Member
Licensed User
Longtime User
It means that only the Firebase connection is working. The certificates are probably misconfigured.

Make sure to use production / distribution certificate and provision profile.

For me certificates and provision profile looks ok.

Are you sure we dont have to write any code here to show notification? by this code itself the notification will arrive?

B4X:
Private Sub Application_RemoteNotification (Message As Map, CompletionHandler As CompletionHandler)
    Log($"Message arrived: ${Message}"$)
    'Msgbox(Message.Get("body"), Message.Get("title"))
    CompletionHandler.Complete
End Sub
 

jazzzzzzz

Active Member
Licensed User
Longtime User
Yes, I'm sure.
Ok please check the screenshots and tell me whats wrong..

1) I have created explicit app id with push notification enabled and created production ssl certificate using my csr file (Please see 1.png fie)

1.png

2) created new production certificate using my csr (Please see 2.png)

2.png

3) created new distribution ad hoc provisonal profile for my explicit app id (See 3.png)

3.png

4) copied all 3 files to key folder and clicked firbase service from IDE
5) uploaded firebase_push.p12 to my firebase console

6)used the newely created certificate and provisonal profile for the app by the following
#CertificateFile:ios_distribution.cer
#ProvisionFile: PushProvisionalAdhocDistribution.mobileprovision
7)Run the application in debug mod

Notification received message is only showed in my log section.
Then I pressed home button and put app in background and sent a push,at that time too message is showed only in the log section of my IDE.

Am I missing something? Please help.!
 

jazzzzzzz

Active Member
Licensed User
Longtime User
1. Where is the code that sends the messages?
2. Can you post the device logs?

logs

B4X:
Application_Remotenotification
Message arrived: (read only map) {
    body = "Stay Tuned1 ...!";
    "collapse_key" = "do_not_collapse";
    from = "/topics/general";
    title = "Sna";
}
Application_Inactive
App Inactive
Application_Background
App Background
Application_Remotenotification
Message arrived: (read only map) {
    body = "Stay Tuned1 ...!";
    "collapse_key" = "do_not_collapse";
    from = "/topics/general";
    title = "Sna";
}

Part of the main code

B4X:
#Version: 1.0.8
    #iPhoneOrientations: Portrait
    #Target: iPhone
    #MinVersion: 8
    #PlistExtra: <key>UIViewControllerBasedStatusBarAppearance</key><false/>
    #AppFont: AvenirLTStd-Black.ttf

    #Entitlement: <key>aps-environment</key><string>production</string>

    #PlistExtra:<key>NSPhotoLibraryUsageDescription</key><string>Select a photo.</string>
    #PlistExtra:<key>NSCameraUsageDescription</key><string>Taking a photo.</string>
    #PlistExtra:<key>NSMicrophoneUsageDescription</key><string>Record video.</string>
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    #CertificateFile:ios_distribution.cer
    #ProvisionFile:pushProvisionalAdhocDistribution.mobileprovision
#End Region

'#If RELEASE
'   #CertificateFile: ios_distribution.cer
'   #ProvisionFile: ios_distribution_appstore.mobileprovision
'#END IF

Sub Process_Globals
    Public App As Application
    Public NavControl As NavigationController
    Public Page1,Referal As Page
    Public kvs As KeyValueStore
    Dim downloadLinks As Map
    Private background As ImageView
    Private login As ImageView
    Public hd As HUD

    Dim parentURL As String
    Dim userDetail,userDetail1 As Map

    Public senderId,parentURL,AccessToken,userID,referalCode,refBy,profilePicLink As String
    Dim parentPicLink As String : parentPicLink = "http://photo_admin/"

    Private referl As TextView
    Private submitReferal As ImageView
    Dim firebaseAnalytics As FirebaseAnalytics
    Public fm As FirebaseMessaging
    Public auth As FirebaseAuth

    Dim strUserName As String
    Dim strInputDialog As String
    Dim txtUserName As String
     Dim newLogin As Boolean
    Private loginEmailBt As Button
    Private SignUp As Button
End Sub

Private Sub Application_Start (Nav As NavigationController)
    NavControl = Nav
'    parentURL="http://livemobtech.com/photocontest/photo_admin/mobile_api.php"
    parentURL = "http://www.medbaltra.com/photo_admin/mobile_api.php"
    Page1.Initialize("page1")
    Referal.Initialize("referal")

    kvs.Initialize(File.DirLibrary,"datastore")

    Dim no As NativeObject = App
    no.RunMethod("setStatusBarHidden:animated:", Array(True, False))

    firebaseAnalytics.Initialize()        
    auth.Initialize("auth")
    ''''''''''''''''''''''
    App.RegisterUserNotifications(True, True, True)
    App.RegisterForRemoteNotifications
    fm.Initialize("fm")
    '''''''''''''''''''''''''
    downloadLinks.Initialize
    If kvs.ContainsKey("regComplete")Then
        If kvs.Get("regComplete") = "yes" Then
            initPageDashboard
        Else
            Page1.RootPanel.LoadLayout("loginPage")
            Nav.NavigationBarVisible = False
            Nav.ShowPage(Page1)
        End If
    Else
        kvs.Put("regComplete","no")
        Page1.RootPanel.LoadLayout("loginPage")
        Nav.NavigationBarVisible = False
        Nav.ShowPage(Page1)
    End If
End Sub

Private Sub fm_FCMConnected
    If kvs.ContainsKey("regComplete")Then
        If kvs.Get("regComplete") = "yes" Then
            Log("FCMConnected")
            fm.SubscribeToTopic("general") 'add ios_ prefix to all topics
        End If
    End If
End Sub

Private Sub Application_RemoteNotification (Message As Map, CompletionHandler As CompletionHandler)
    Log($"Message arrived: ${Message}"$)
    'Msgbox(Message.Get("body"), Message.Get("title"))
'    Dim ln As Notification
'    ln.Initialize(DateTime.Now)
'    ln.IconBadgeNumber = 1
'    ln.AlertBody = Message.Get("body")
'    ln.PlaySound = True
'    ln.Register
    CompletionHandler.Complete
End Sub

Private Sub Application_Background
    Log("App Background")
'    fm.FCMDisconnect 'should be called from Application_Background
End Sub

Private Sub Application_Inactive
    Log("App Inactive")
 
End Sub

Private Sub Application_Active
    Log("App Active")
    App.ApplicationIconBadgeNumber = 0
    fm.FCMConnect 'should be called from Application_Active
End Sub
 
Last edited:

jazzzzzzz

Active Member
Licensed User
Longtime User
That's the mistake. You should use the B4J code from the tutorial. Next time when you ask a question make sure to post all the relevant information.

I thought sending tool will be same as the android thing.!!!
Am sorry now it works..
So iOS sending tool have more data fields in the json write?..and that's the issue I was facing..!
 

JohnnyHamburg

Member
Licensed User
Longtime User
Hello,
I have some issues following this tutorial. Maybe someone can help me.
At first I can only download an 'aps.cer' file from apple, but not 'aps_*.cer' like it is meant. I tried out serveral times. Is this correct?
And then on uploading the firebase file to google, it asks me for a Production-APNs-Certificate password. But I can not find a password like this.
Do I have to build a new Key from "Private Sign Key"?
Or where could be my fault? I tried already several times.

Ok, somehow it works now. Seems Google didn`t make it at that moment. Had to put my password from 'Private Sign Key' at uploading the certificate to firebase.
 
Last edited:
Status
Not open for further replies.
Top