Sending Firebase Push Notifications - Firebase Cloud Messaging

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey guys welcome back to new video and this video I will show you how we can show push notifications using firebase so those notifications will be displayed on every device we want it to be displayed so as you can see I can enter a title here for example hello what's up as a description and if we now click on send then this notification will be displayed you can see on both devices but also on this device and of course I will also show you how to only send this notification to the other device so that it doesn't get displayed on this device that's what this token at the text field here is for but don't worry about that for now I will explain this in detail and also how we can get that token I already assumed that you connected firebase to your owner to your project and also setup the firebase Cloud messaging dependencies correctly you can check that under the tools tab here in the father's assistant then this will open up you go to the cloud messaging tab open up the blue link and both these options here should stay say connected and dependencies set up correctly if you haven't done that then make sure to do that before starting this video if you don't know how to do that then just check out my video about how to connect five-eights to your under studio project then what you also need is the dependencies I have you can see I have the file based messaging dependency that should be added if you include that firebase cloud messaging functionality with that 5 s assistant I showed you before then you need curtains dependencies because we're going to use retrofit so make sure to use those dependencies to retrofit will be needed here to make a post request to the fire based API so that 5s actually knows when we want to show that push notification to other devices and since I like to use retrofit in combination with curtains we also want to include those coroutine dependencies here then you can see my layout file is set up like that because that's not the focus of this video I won't show you how to do this you should be able to create a similar layout or simply get this layout from this video's description they can find my github repository simply copy paste the XML code and then we are actually good to go and can jump into main activity and start with coding as a first step I want to declare some constant values that we need to use the firebase API for that I like to create a new class called constants select class here and inside of that class we will create a companion object and open that up so we can access those constants from everywhere the first one will be a constable for our base URL if you use retrofit before then you know what this is for that is just the URL we are going to make our request su and that will be set to HTTP FCM that stands for file based cloud messaging that Google API scrum and the next one will be your firebase Cloud messaging server key so we write constable server key and you will get this server key from your firebase console so I will show you how to get this so make sure to go into your firebase console that is the project I connected to my Android episode really make sure to choose the same one then we want to go to this Settings tab here and go on project settings then on cloud messaging and here you can see that is my server key right here we want to copy that and go back to inroads to you and simply paste this in those quotation marks here and as a last variable here inside of this constants class we will declare the content type of our request so content type that will be application slash Jason that's just the format we need to put our request in to make that request to firebase you can simply see that in their documentation that we need exactly that content type to make our request otherwise it will throw an error the next step will be to create our data classes for retrofit so we can actually post that notification body let's go to our root package and create a new class select class here and I will call this notification data that will be a data class here and inside of the constructor of the data class we will have a title that is a string and we will also have a message which is also stream so that will be the title of our notification and that will be the message so basically the description of it and then now when we have that notification data we can create another data class called push notification which is also a class of course also make this data class and inside of this constructor here we will have the data parameter and also make sure to really call it the same as I do because that's how the parameters must be called for that request that data will now be of child notification data we declared before and this class will also have a parameter called 2 which is a string and that will basically be the recipient of our push notification so we can later either pass a topic here we want to send this notification to so that means all the devices that subscribe to that specific topic that we can declare will receive that notification or what we can do is we can pass one or several recipient tokens so that is just a unique identifier for a specific device or for specific instance of that app so that is just needed to send that notification to your specific device and not to all devices who subscribe to that topic but you don't need to understand that for now I will explain this in detail when we get to that point so now that we have both of our data classes that we present the request body basically we can now create our actual API interface so make sure to create a new carbon file class select interface here and I will call this notification API create that interface and in here we will have a single function which will be a suspend function because we will use cout routines here we will execute that function asynchronously because it's a network request I will call this function post notification and this function will take as a body parameter so the data to attach to this function the notification that we want to send with this basically will be a notification of type push notification and the return value of this function will be a response of type response body and make sure to import response here not from the okay HTTP 3 library instead from the retrofit to library you really make sure to import this one and then on the one hand we need to annotate this function with at post because this is a post request we need to pass the URL of that post so that will be attached to the base URL be declared in our constants class that is our base URL and the URL we need to specify here is basically the part after that that will just be the FCM slash send you can also find that in the documentation of firebase Cloud messaging and we also need to annotate this function with add headers because we need to override the default headers for this request because on the one hand we need to overwrite the authorisation of that request because we want to pass our server key in the request header for that we simply pass authorization : key is equal to and now we want to pass our server key here from our constants file so we write server key make sure to press alt + Enter to import that server key and as a second parameter of this headers we want to pass the Content ID you can see that we also declared the content type here in our constants file and the server key both of that is needed for our request so make sure to pass content type : and here we simply pass our content type from our constants file and I just realized I have a little typo here authorization of course and that is basically it for this notification API the next step is to actually create our retrofit instance so we create another class for that Carbon fellow class I will call this retrofit instance select class here and inside of this class we will create a companion object we will have a private Val retrofit by lazy you don't know what lazy is that just means this variable here will only be initialized if we need it so by default that won't be initialized but once we access that variable for the first time then it will be initialized and then it will have the value we declare inside of this lazy block here and this value will be retrofit builder dot base your L here we're going to pass our base URL from our constants fault base your L make sure to import that and add a converter factory for the JSON files so that will be a decent converted factory dot create and then we can simply call that build afterwards next we also need to create our actual API that we can get from that retrofit instance here so let's create another Val here Val API which is also initialized by lazy and that simply returns retrofit dot create and here we pass our notification API class dot Java so as you can see now we access that retrofit instance that we declared here by lazy so only when we access it here then this will actually be executed and not before that so now we can actually go back to our main activity and cut a function that makes that actual Network request so that sends that notification to our phase server that will be a private function send notification and it will take our notification as a parameter which is of child push notification and this function will start routine routine scope in the IO dispatcher dispatches at IO dot launch and inside of this COO routine we now want to open a try and catch block to be able to catch exceptions so just e call an exception here in that case I simply want to lock that error I will create a tag for that and also import lock and simply print edat to string let's create that tag here well tag is equal to main activity and instead of this triblock we will make our request actually so that will be a well response so the response of our request will be retrofit instance dot API dot first notification so that is our actual post function from our API interface here and as a parameter we simply has our notification here and after that we can check if that response was successful if it was then we simply want to make a debug log here pass our tag and simply print that response for example and that will be we recorded G's in here to actually be able to dis you realize that we have to make curly brackets gisun dot to Jason so we can actually print that JSON response that will be the response here inside of that parameter and if that response was not successful so in the else block will simply make another error log pass our tag and print our response that error body to string then we want to execute that function when we click on our send button so instead of our own create function we will call button send dot set on click listener first we want to get the title of that notification from ete title text at to string and we want to get the message for that notification from EG message data text that to string then we can check if our title is not empty and also our message is not empty and if they're not then we want to create a topic we want to send this notification to so let's actually do this up here as a global variable that will be a Val topic or actually let's make this a constable constable topic is equal to slash topics and here we can name it whatever we want I will call it my topic here so what we can do with this topic is we can let our app subscribe to specific topics and then we can declare a topic when we send that notification so that notification will be sent to all devices who subscribe to that specific topic and that's exactly what we are going to do here first later I will also show you how to send a notification to a specific user so just to a single user not to all users who subscribe to that topic but first of all let's create a push notification here and that will contain a notification data we pass our title and message here and as the two parameter so to whom we want to send that notification we simply pass our topic and then we can call that also afterwards and call send notification and pass it so that will be enough to send notifications but for now we don't have any functionality to receive them and to actually receive them we need to create a service because we also want to be able to receive them when our activity or when our app is closed we need to create a service that runs in the background and is nullified when we get a new notification so let's go to our project package and create a new class select class here and that will be our firebase service that plus will inherit from firebase messaging service and in here we can override a specific function called on message received I'll actually rename this parameter to message so that will be the function that is called whenever this device receives a message so in our case here whenever the device that subscribe to this topic gets a new message inside of this topic then this on message receive function will be called and then we can get that message from this message parameter here so what we want to do inside of this five s service class now is whenever we see if that message inside of this function we want to create a notification and show it and if you don't know how to display a notification here then I suggest to watch my video about that first in my Android fundamentals series because I won't go into too much detail about this but anyways let's create an intent here that we're going to use to open up our main activity when we click on that notification that will be an intent we need to import that here pass this as a context and our main activity double call and class a Java then we will have our notification manager which we'll get from get system service context dot notification service and we need to cast that to notification service notification manager then we have to give our notification and ID to uniquely identify it I will just randomly generate one here notification ID and set it to random make sure to select that Kotlin that random dot next int so by doing this we just make sure that we always have a different ID because if you would use the same ID then the old notification would be overridden by the new one and we rather want to have two notifications display at the same time or three or even more so you you get what I mean then I will add a flag to our intent intent out add flags and that flag will be intent dot flag activity clear job that will just make sure when we click on our notification that all activities that are not our main activity will be cleared until our main activity is on top of our stack not really important in our application here because we only have a single activity but I think you should add that if you plan on implementing this functionality in an app with several activities of fragments and you can have a back stack that is just greater than one after that we can create our pending intent from our intent that we created before we are going to set that to panning intent dot get activity here we're going to pass this for the context I will just pass zero for the Kress code we're not going to need this and has our intent that we created before and as a flag for this painting intent we want to pass the flag one shot which we need to import here that is just used to declare for that painting intent that it can only be used once so whenever we click on our notification then this pending intent is basically consumed and after that it cannot be used anymore because then we open up our activity next we can create our actual notification so well notification and set that to notification compat dot further and inside of this builder we need to pass our context and a channel ID for our notification channel so since android oreo we have to create a channel for our notifications that i'm going to do in this tutorial too of course because otherwise this won't work but we have to declare an ID for that channel and i will make this ID constant up here that will be a Const well actually we can make this a private console because we are only going to need this inside of this service class and I will call this channel ID and set it to my channel I don't know choose anything you want and then we can simply pass that my channel or the channel ID in our builder constructor then we can let's actually make a little space here so I can read that better after that we can modify that notification we can set the content title to our message so the message we received from firebase dot data and we want to get the title of that data so we can basically treat this message very similar to a hash map or actually this this data here is a map you can see so just key value pairs we can access the title and get the title all of that data and we can do the same for the actual message so we can write set content text instead and here we want to pass message that data and instead of the title we want to get the map which then what we also need to declare is a small icon for a notification so we call set small icon and I don't have an icon for that yet so let's quickly import that in our res folder right click on drawable vector asset and I will just choose this very basic Android notification here but you can click on clip art here and choose any icon you want just click on next and finish and then we can pass that icon by writing our draw a dot I see Android black then we want to set auto cancel to true so basically that the notification is deleted when we click on it and set the content intent of that notification to our pending intent recreated above and then we can call that build afterwards and now when we have that notification variable we can actually display it so we can use our notification manager we created above and call that notify on that we have to pass our notification ID and we have to pass our actual notification and as I said after Android earlier or actually also for Android or EO we need to create a notification channel we want to send that notification into so let's create a channel in a separate function that will be a private function create notification channel that will take our notification manager as a parameter and inside of that function block will have a valve for that channel name doesn't really matter what you choose here I will just choose channel name then we will have the actual channel so where channel is equal to notification channel where we are going to pass our channel ID then our channel name and the importance underscore height which we are going to import from this year notification manager then we can call that apply afterwards and here we can modify that channel as we want with give it a description my channel description choose whatever you want here it's also not very important we can enable the lights so that notification actually lets our devices LED light blink and we can also set the light color of that LED light to color the green for example choose whatever you want here and after that we can call notification manager dot create notification channel and pass our channel here and as you can see we get a bunch of arrows here if we hold on to this this call request API level 26 and our current minimum is 21 so just click on add requires Android annotation and then these errors will be gone then we need to make sure to actually call this function up in our own message receive function right at this point here we will check if our build dot version dot SDK int is greater than or equal to build version codes dad oaks or Android Oreo if that is the case we want to call our create notification channel function and pass our notification manager and that is everything for now for our service class now the only thing we need to do to actually be able to receive notifications inside our topic here or my topic is we need to make some changes in our manifest file so let's open that and first of all we need to permissions here so open our by users permission here first of all internet permission for a retrofit request then we can duplicate that and we also need the permission to receive messages from firebase that will be become that Google dot Android dot C to the m dot permission that receive so don't worry if that doesn't appear for you in the other suggestions that's normal and what we also need to add here is our actual service that we created before so make sure to do that inside of this application tag we will open a service tag here pass our firebase servers it already suggests it then we can also add a permission to that service so inside of the service tag we add that permission tag come Google Android c2dm permission sent so that will just be the permission to send notifications which we'll need for that service and inside of this service tag when we open that up we will add an intent filter which will also open up here first of all we want to add an action to that intent filter with the name com Google fire braze dot messaging event messaging event you can also find all these packages here in the firebase documentation so if you wonder from where I know that and we will have an action here with a name comm Google dot Android dot c2dm intent dot receive that is also just needed to be able to receive messages and currently we are able to send notifications into that topic here we declared above but we haven't subscribed to that topic yet so that's the last thing we need to do to actually be able to receive messages inside of this topic but that is just a single line that is firebase messaging dot get instance dot subscribe to topic and here we are going to pass our topic and to test if it is actually working I will launch both of my emulators with the same app of course and take a look here I will choose hello as a title and guys as a message and when I now click on send it should send this notification with the title hello and the message guys into our my topic here and every app that subscribed to that my topic will now receive that notification so that means that also the the app that was that this notification was sent from will receive that notification because both of our apps subscribed to that topic so let's click on send and you can see the notification pops up in both devices so that is exactly working as expected but as I said I will also show you how we can only send that notification to a single device or to several devices that we specifically declare and for that we want to go back into Android studio so when using 5 s Cloud messaging every device of basically every instance of your app will have a unique registration token assigned and that registration token can now be used to send that notification to a specific device so when we use that registration token and pass it instead of this topic here then this notification will only be sent to this registration token so only the the device with that token will receive that notification so the first thing we need to do here is we need to actually find out what is our registration token and we're going to do this up here we can get this by writing firebase instance ID that getinstance dot instance ID and here we can add an on success listener to that where we can receive our notification token by writing it dot token so what I will do here is I will set the text of our token edit text so eg token to that token to it dot token so that we can simply copy that token from that edit text and paste it in our other app to tell our app that it should only send that notification to that specific token so to our other app however if you use that in a real project then you definitely don't want to do that like this of course then you rather want to save that chokan for each user in a remote database so for example in file store and if you then have a chat application for example and you want to send a chokan to a specific user ID that it can use that user ID to get the token of that user from your file store database and then send a message to that token or notification and generally it is also best practice to save that token in share preferences so that's what I will do here I will do this in our firebase service because you can see we get one in here if we hold on to this apps that use fiber cloud messaging should implement on your token in order to observe token changes so whenever that token changes that can happen then we of course want to update our current token and that will happen inside of this five a service class so I will solve this by creating a companion object here so we can access that token from everywhere yeah I will we will have an instance two of our shared preferences objects of our shared prep is equal not equal to it's of type share preferences which is nullable and going to set it to null initially we have to set that shared preferences variable from the outside because we cannot access our o58 service class from within our companion object that's why we have that shared preferences variable there and we're going to set this inside of our activity class then we will have our chokan solve our token that is inaudible string and for the token I will overwrite the default getter and setter because when we get that token what we want to do is we want to return the token from our shared preferences so we turn a shared preferences dot to get string token and in case that is not available then we simply want to return an empty string and in the setter we will have our value so the new value for our token and we will use our shared preferences object to call that edit and call that foot string we want to put the token with the value value and call that apply afterwards to write this into our shell preferences by the way sometimes you also see people calling commit but that is synchronous and apply is asynchronous so that will happen in the background so always make sure to use apply for shared preferences and if you're not familiar with getters and setters in Kotlin that just over eyes the default getting and setting of our tokens so whenever we would write print token example then we would get the value of the token and instead of getting the actual value of the token we will instead get this value so the value from our shared preferences and if we assign a new value to our children served by token is equal to anything then we will actually use this setter here and the value will be that new string so we will save that new string in our shell preferences that's what these getters and setters mean and then we want to override on new token as that one here says that we should all write that function I will name this parameter new token so whenever we get a new token then this function will be called and we can save that new token in our shared preferences so we can simply use our token variable and set it to our new token and then it will automatically be saved in our shared preferences because we set the setter here according to that and then we want to go back to our main activity and actually assign that token that we got from here to our service token so firebase service that token is equal to each star token and also we shouldn't forget to set the shared preferences object in our firebase service in oncreate so we have to make sure to do that before we get our token we just call our 5s service dot shared preferences and set it to get shared preferences we have to give the name of ecologist shared prep and open it in mode private and now instead of sending this notification here to a specific topic instead we want to send this notification to our token so to the token we declared in the edit text field I will get this token by writing Val chokan or actually let's call it recipient token and that is equal to ET token dot text to string we can also check if that is not equal to null and recipient token that is not empty and then simply pass that instead of the topic and let's actually try that out and run both of our apps in both of our emulator and as you can see the token is now displayed in the edit text for that token and if we now want to send a notification from this device to this device then we need to copy the token of the recipient so copy and instead of this text here we want to paste our token from the other activity click on paste so that will now be the recipient token we can enter a child hello guys and click on send and then only this device will receive that notification as you can see and yeah as I said normally you wouldn't of course do it like this with that edit text field and the token that is just for simplicity in this tutorial usually you have user accounts and for each user account you save that token as a parameter in a database and then you can simply receive that token whenever you want to send a message to that particular user so that was a rather long tutorial but I still hope that it helped you because a lot of people requested such such a tutorial and also please tell me below what you think about this kind of tutorials because for now I always made two toriel's that cover an entire series so a more complex project but I'm thinking about making more of these mini projects basically that just that I can cover in a single video so please tell me below if you liked this video that would be really helpful for me and have a good day see in the next video bye bye [Music]
Info
Channel: Philipp Lackner
Views: 107,652
Rating: undefined out of 5
Keywords: tutorial, android, development, learning, programming, programmer, kotlin, beginner, firebase, free, backend, service, database, realtime database, setup, newbie, english, cloud messaging, push notifications, remote, detailed, network, fcm, chat, chat app, chat application, instant messenger, messenger, messages
Id: HoFWPPv1ih8
Channel Id: undefined
Length: 35min 25sec (2125 seconds)
Published: Wed May 20 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.