Skip to content

Instantly share code, notes, and snippets.

@oddmario
Last active June 27, 2023 13:41
Show Gist options
  • Save oddmario/357ad6f173f736c914b229cf4f4f154f to your computer and use it in GitHub Desktop.
Save oddmario/357ad6f173f736c914b229cf4f4f154f to your computer and use it in GitHub Desktop.
Send push notifications in an Android app (Java) using Firebase Cloud Messaging

Used sources

How does it work?

  1. Follow the "SETUP FIREBASE PROJECT" and "Connecting Firebase With Android" bits at https://medium.com/codex/complete-guide-on-sending-push-notifications-on-android-using-firebase-82a4c2f7f3a7 to create a new Firebase project and link it to your app.
  2. Install the Firebase SDK into your app (see the build.gradle files included in this gist for reference)
  3. Create a MyFirebaseMessagingService class in your app (see the MyFirebaseMessagingService.java file included in this gist for an example)
  4. Register the Firebase service (<service></service> tag) in your AndroidManifest.xml file (see the example file included in this gist if you want)
  5. Initialize Firebase in your app startup (in the main activity). Also you can optionally subscribe to a topic so you can identify your users' devices and send notifications to them individually if you want later. (See the MainActivity.java class included in this gist for an example)
  6. You can now either use the Firebase console to send a test notification, or write your own backend implementation that'll send the proper API requests to Firebase (See the Backend code.js file included here for an example in Node.js)
  7. Also optionally if you want, you can customize the MyFirebaseMessagingService class to handle the notifications on your own (i.e. if you want to create custom notification channels, etc). See "Displaying the Notification" at https://medium.com/@Codeible/android-notifications-with-firebase-cloud-messaging-914623716dea for an example

Notifications are a message or alert that is displayed on the device, while push notifications are messages that are sent from a server to the device.

If you want to send local offline notifications even when the app is closed, it's preferred to see all the answers of this Stackoverflow question: https://stackoverflow.com/questions/39674850/send-a-notification-when-the-app-is-closed

  • final note: i'm not doing this again :dead:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MyApp"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
</application>
</manifest>
const bodyparser = require("body-parser");
const express = require("express");
const admin = require("firebase-admin");
/*
See "SET UP NODEJS BACKEND" at https://medium.com/codex/complete-guide-on-sending-push-notifications-on-android-using-firebase-82a4c2f7f3a7 to learn how to get your own JSON file
*/
var serviceAccount = require("./firebase_serviceAccount_file.json");
// init
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
});
const app = express();
app.use(bodyparser.json());
const port = 3000;
app.get('/send', (req, res) => {
var message = {
android: {
ttl: 30 * 1000 // 30 seconds,
priority: 'high',
notification: {
title: 'Hello!',
body: 'This is a test notification :)',
color: '#2C5AE1',
}
},
topic: "appTopic" // send the notification to just the 'appTopic' topic.
};
admin.messaging().send(message)
.then(response => {
res.status(200).send("Notification sent successfully");
})
.catch(error => {
console.log(error);
});
});
app.listen(port, () => {
console.log("Listening to port " + port);
});
plugins {
id 'com.android.application'
id 'com.google.gms.google-services'
}
android {
namespace 'dev.mqrio.TestNotifsApp'
compileSdk 33
defaultConfig {
applicationId "dev.mqrio.TestNotifsApp"
minSdk 24
targetSdk 33
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_15
targetCompatibility JavaVersion.VERSION_15
}
}
configurations {
compile.exclude group: "junit", module: "junit"
}
dependencies {
implementation platform('com.google.firebase:firebase-bom:32.1.1')
implementation 'com.google.firebase:firebase-analytics'
implementation 'com.google.firebase:firebase-messaging:23.1.2'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.5.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}
apply plugin: 'com.google.gms.google-services'
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google() // Google's Maven repository
mavenCentral() // Maven Central repository
}
dependencies {
classpath 'com.google.gms:google-services:4.3.15'
}
}
plugins {
id 'com.android.application' version '8.0.2' apply false
id 'com.android.library' version '8.0.2' apply false
}
package dev.mqrio.TestNotifsApp;
import android.content.Context;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import com.google.firebase.FirebaseApp;
import com.google.firebase.messaging.FirebaseMessaging;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
appContext = getApplicationContext();
// Initialize FirebaseApp
FirebaseApp.initializeApp(this);
FirebaseMessaging.getInstance().subscribeToTopic("appTopic");
}
}
package dev.mqrio.TestNotifsApp;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
public class MyFirebaseMessagingService extends FirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment