TODD KERPELMAN: So you probably already know
that Firebase Cloud Messaging not only sends messages
to Android devices, but it can also route notifications
through APNS, Apple's Push Notification Service,
to talk to iOS devices.
But I think it's worth explaining how it does this,
partly because it's kind of interesting, but more
importantly because it can give you an understanding of what
to look for if things go wrong.
Let's explore further on this episode of "Firecast."
So two things are needed for any service
to communicate with APNS.
First you need a certificate, which basically
allows you to communicate with the APNS servers
in the first place.
These days I know you can also use something
known as an APNS auth key, which is
a little more convenient to work with if you're writing
your own communication code.
But I'm going to focus on the certificate for now,
because this is what Firebase Cloud Messaging currently uses.
Second, you'll need to tell APNS what device you
want to send a notification to.
And for that you need a device token.
It's essentially a way to uniquely identify
this user's device using an identifier that
only works with your app.
So this device token is something
that's typically requested from APNS by the device,
and then sent down to your server.
Since Firebase Cloud Messaging is
taking the role of the server here,
it needs these two things, the certificate
and the device token.
So one of the first things you do when you set up
Firebase Cloud Messaging is to upload your APNS certificate,
in the form of a p12 file, to the Firebase console.
And this allows the FCM server to talk to APNS.
Then when your app starts up, your user's device
will request a device token from APNS.
It will then send that token down
to Firebase Cloud Messaging.
And then Firebase Cloud Messaging
will create and send back a copy of its own device token
in exchange.
So at this point, FCM has everything
it needs to communicate to your device using APNS.
And now you're ready to send off your request through Firebase
Cloud Messaging.
So just like with APNS, you need two things
to send a notification request through FCM-- a way
to communicate with the service and a way
to identify your target device.
So first off, instead of a certificate,
you're going to use an API key, which
you can think of as the secret password you
need to talk to the FCM server on behalf of your app.
And you can get this from the Firebase console.
Next, assuming you want to talk to individual devices,
you'll also need the FCM token, which
you'll get from your client.
These two pieces of information are then
packaged up into a notification that you send off
to Firebase Cloud Messaging.
Now Firebase will look at whatever entry
it has for the device with the matching FCM device token,
and it will see that it's associated with an APNS token.
So it says, ah, I probably need to route
this message through APNS to talk to this device.
So what Firebase will do is it will create a new APNS
version of this notification, using
the certificate and the token that it has stored on its side.
This new notification will then get
sent to APNS, which will then notify our iOS device,
and your notification will finally show up.
Hooray.
So I know, that's kind of a lot to process, right?
But if there are two things I want
you to take away from this explanation, it's this.
First, most of this work is being
done behind the scenes for you.
Most of the time you don't need to know or care
about any of it.
Second is that by the time you get to here,
this is just a regular old APNS notification.
As far as your app is concerned, this notification
looks like any other notification it
might have received from Apple.
So let's stop and think about the work our device had
to do during this process.
We had to, one, ask APNS for a device token, two,
send that APNS token off to FCM, and then three,
receive back the FCM device token.
Well, getting an APNS device token
is accomplished by calling registerForRemoteNotifications
the way you normally would.
As for these other steps, you don't really
need to do any work to make this happen.
As long as your app has Firebase enabled,
we do most of the work for you thanks to some fancy method
swizzling.
If you're new to the concept of method swizzling,
it's basically a way developers can add on functionality
to preexisting methods in iOS by calling a custom
version of that method, which usually then calls
the original method when it's done.
Now often developers use these to customize
methods that are part of the standard iOS library.
But in our case, we're using them
on top of any delegate methods you might have written.
So in our swizzle didRegisterForRe
moteNotifications call, we receive the APNS token
and send it off to Firebase Cloud Messaging in exchange
for an FCM device token.
By the way, I've actually been lying to you a little bit.
This token is really known as an InstanceID token, which
in theory could be used to identify
your device for services other than just Firebase Cloud
Messaging.
And that's why you'll see it created by the InstanceID
library in our code and why it's sometimes
called your registration token in the docs.
But for the purposes of understanding FCM,
I think you're better off just calling this an FCM device
token, because this is basically what it is.
I should also point out that we swizzle some of the methods
for receiving notifications as well.
And what we're primarily doing here
is making sure that we're recording analytics information
about these notifications.
This is how we can give you some of those nice,
hey, 30% of these notifications were opened reports
that you see in the Notifications panel.
And if you're uncomfortable with the idea of having
somebody else swizzle your methods,
you're more than welcome to turn this off.
You'll just have to add in the code manually
to do the work that we're doing.
And we've got documentation for that.
Finally, one last note with these swizzled methods
is that we don't automatically call anything
that would bring up that standard iOS dialog asking
the user if it can show any user visible notifications.
We know that this is something you probably
don't want to call until you're pretty sure your users are
actually going to say yes.
So this method will still be up to you
to call at the moment that makes the most sense for your app.
Of course now that I've told you that this
is nothing more than a plain old APNS notification
and you don't need do anything special to use Firebase Cloud
Messaging, you might notice the section in our documentation
where we ask you to explicitly connect
to Firebase Cloud Messaging.
So what's that all about?
Well you see, in addition to being
able to communicate to your device through APNS,
you can also connect through Firebase Cloud Messaging
to receive notifications directly through that service.
But there are some restrictions here.
First and foremost, this only works if your app
is in the foreground.
Second, this only works for data-only messages-- nothing
with an alert message, badge, sound, anything like that.
It also doesn't work with content-available messages.
Those will always go through APNS.
In fact, in APNS land, I don't think
you're allowed to send a silent notification that doesn't
include content-available.
So this type of message is only valid through Firebase Cloud
Messaging, as far as I can tell.
So if you send this type of notification
and your app isn't in the foreground
and hasn't explicitly connected to FCM,
it won't receive this message until you reconnect.
So of course the question you might have is,
why would you ever want to do this?
So communicating directly through Firebase Cloud
Messaging does have some advantages.
For one thing, FCM tends to be more
aggressive about getting these data messages to their target
device.
For another, there's just one fewer hop for your message
to take, which is always nice.
And also, your device could actually
send back upstream messages through FCM
to let you know, for instance, that this message was received.
But because they only work in the foreground,
their use case is kind of limited to apps
that are generally OK with not receiving these notifications
in the background.
One good example-- YouTube.
Their iOS app uses the FCM connection to deliver room chat
for its YouTube Live events.
Since this app really only cares about getting
this avalanche of chat messages when it's in the foreground,
it's a pretty good use case for Firebase Cloud Messaging.
But if you don't think your app is
going to need these types of messages,
I might recommend not connecting to the FCM service
directly, at least until you've gotten the rest of Firebase
Cloud Messaging working.
It's just one extra factor to deal
with when you're trying to track down issues with your APNS
implementation.
So there you go.
That's how FCM works on iOS devices in an overly simplified
nutshell.
Hopefully this gives you a little more insight into what's
happening behind the scenes.
And if you found this video helpful, be sure to subscribe.
And we will see you soon on another episode of "Firecasts."
Thank you very much for watching.
Want some more exciting Firebase content?
Well check out these videos here.
Jazz hands.