Android Firebase for beginers
Firebase
I. What is Firebase
Google Firebase is a Google-backed application development software that enables developers to develop iOS, Android and Web apps. Firebase provides tools for tracking analytics, reporting and fixing app crashes, creating marketing and product experiment. Firebase has many services and today I’m going to introduce to in-app messaging, cloud messages and real-time databases.
II. Add Firebase to your app
Before you integrate Firebase into your Android app, you need to create a Firebase project to connect to your Android app. log in to Firebase console in this link https://console.firebase.google.com/?hl=en
Step 1: After you signed-in to Firebase, click on “Create a project“.
Step 2: There are steps to take to create a new Firebase project. Click on Android icon.
Step 3: Enter your “Android package name” the same as package name in AndroidManifest
Step 4: Download “google-services.json” and add to the project.
- Click on Project to switch view, you will see the root directory of the project . Put the “google-services.json” file into “Project/~/app” folder.
Step 5: Add Firebase SDK.
1. In “build.gradle” (Project):
2. In “build.gradle” (app):
Step 6: Run and wait Firebase verify the app, you will see message when success, click on “Continue to console”.
III. In-App Message
1. Introduction
Firebase In-App Messaging helps you engage your app’s active users by sending them targeted, contextual messages that encourage them to use key app features. For example, you could send an in-app message to get users to subscribe, watch a video, complete a level, or buy an item. You can customize messages as cards, banners, modals, or images, and set up triggers so that they appear exactly when they’d benefit your users most.
2. Get start
Step 1: Add “implementation ‘com.google.firebase:firebase-inappmessaging-display:19.0.3’ into “build.gradle” (app) and Click “Sync Now“.
Step 2: Get Firebase instance ID (this id’s used to test in-app message on Firebase).
private fun createInstanceId() { FirebaseInstanceId.getInstance().instanceId.addOnCompleteListener { task -> if (!task.isSuccessful) { Log.w(TAG, "getInstanceId failed", task.exception) return@addOnCompleteListener } //create new instance id Token val msg = task.result?.id Log.d(TAG, "token: $msg") } }
Step 3: Run the app and open “Logcat” tool, we will see the ID token.
Step 4: Copy the ID token, open Firebase console -> “In-App Messaging“, click “Create your first campaign”.
Step 5: Enter “Message title” (ex: Hello I’m FireBase), “Body” (optional), “Images” (ex: https://cdn.pixabay.com/photo/2015/10/12/14/54/coffee-983955_960_720.jpg)
Add “Button text“.
Step 6: Click “Test on Device”, and paste the ID token into “Add an instance ID” field.
Firebase In-App Messaging sends the test message as soon as you click “Test“. To see it, move the app to background, then re-open the app on your testing device.
Result:
Step 7: After test successfully, click “Next” to continue.
Click “Review” to publish your message.
When click “Publish” message will send to the app.
Result:
IV. Cloud Message
1. Introduction
Firebase Cloud Messaging (FCM) is a cross-platform messaging solution that lets you reliably send messages at no cost. Using FCM, you can notify a client app that new email or other data is available to sync. You can send notification messages to drive user re-engagement and retention. For use cases such as instant messaging, a message can transfer a payload of up to 4KB to a client app.
2. Get start
Step 1: Add “implementation ‘com.google.firebase:firebase-messaging:20.1.0’ “into “build.gradle” (app) and Click “Sync Now“.
Step 2 : Add filter to AndroidManifest file.
<service android:name=".java.MyFirebaseMessagingService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service>
MyFirebaseMessagingService is a service that extends FirebaseMessagingService. This is required when you want to do any message handling beyond receiving notifications on apps in the background. To receive notifications in foreground apps, to receive data payload, to send upstream messages, and so on, you must use this service.
Now you will see an error at line 23. This is occurred because we don’t have MyFirebaseMessagingService file in project so let create it.
Change package name from .java.MyFirebaseMessagingService to <package>.MyFirebaseMessagingService.
Step 3 (optional): Set a default icon and color, you can skip this step if you do not want icon and color in your notification.
<!-- Set custom default icon. This is used when no icon is set for incoming notification messages. See README(https://goo.gl/l4GJaQ) for more. --> <meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/ic_stat_ic_notification" /> <!-- Set color used with incoming notification messages. This is used when no color is set for the incoming notification message. See README(https://goo.gl/6BKBk7) for more. --> <meta-data android:name="com.google.firebase.messaging.default_notification_color" android:resource="@color/colorAccent" />
Step 4 (Optional): From Android 8.0 (API level 26) and higher, notification channels are supported and recommended. FCM provides a default notification channel with basic settings. If you prefer to create and use your own default channel, set default_notification_channel_id to the ID of your notification channel object as shown; FCM will use this value whenever incoming messages do not explicitly set a notification channel. To learn more, see Manage notification channels.
- Goto res/values/strings.xml and add this line.
<string name="default_notification_channel_id">1</string>
- Open AndroidManifest file and add this code.
<meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="@string/default_notification_channel_id" />
Step 5: Open MainActivity to retrieve the current registration token, add this function
private fun createInstanceId() { FirebaseInstanceId.getInstance().instanceId.addOnCompleteListener { task -> if (!task.isSuccessful) { Log.w(TAG, "getInstanceId failed", task.exception) return@addOnCompleteListener } //get id Token // Get new Instance ID token val token = task.result?.token // Log and toast Log.d(TAG, "token: $token") Toast.makeText(baseContext, "token: $token", Toast.LENGTH_SHORT).show() } }
- Run the app, to get Firebase instance ID.
Step 6: Add the code below into the MyFirebaseMessagingService class.
class MyFirebaseMessagingService : FirebaseMessagingService() { companion object { private val TAG = this::class.java.simpleName } override fun onNewToken(token: String) { Log.d(TAG, "Refreshed token: $token") super.onNewToken(token) } override fun onMessageReceived(remoteMessage: RemoteMessage) { super.onMessageReceived(remoteMessage) Log.d(TAG, "From: ${remoteMessage.from}") remoteMessage.data.isNotEmpty().let { } remoteMessage.notification?.let { Log.d(TAG, "Message Notification Body: ${it.body}") it.body?.let { body -> sendNotification(body) } } } private fun sendNotification(messageBody: String) { val intent = Intent(this, CloudMessageActivity::class.java) intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP val pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT) val channelId = getString(R.string.default_notification_channel_id) val defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION) val notificationBuilder = NotificationCompat.Builder(this, channelId) .setSmallIcon(R.drawable.ic_notifications) .setContentTitle("Mess Title") .setContentText(messageBody) .setAutoCancel(true) .setSound(defaultSoundUri) .setContentIntent(pendingIntent) val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val channel = NotificationChannel( channelId, "Channel human readable title", NotificationManager.IMPORTANCE_DEFAULT ) notificationManager.createNotificationChannel(channel) } notificationManager.notify(1, notificationBuilder.build()) } }
Step 7: Test Cloud Messaging.
Enter Notification Title, text and image (optional) ex: https://cdn.pixabay.com/photo/2017/07/07/02/05/symbol-2480161_960_720.png and send test message.
- Add the token we got from Logcat (step 5)
- Result:
Step 7: Create and send message.
After test successfully, click “Next” to continue.
- Click “Publish” to send a message.
Result:
V. Realtime Database
1. Introduction
The Firebase Realtime Database is a cloud-hosted database. Data is stored as JSON and synchronized in realtime to every connected client. When you build cross-platform apps with our iOS, Android, and JavaScript SDKs, all of your clients share one Realtime Database instance and automatically receive updates with the newest data.
2. Get start
Step 1: Add “implementation ‘com.google.firebase:firebase-database:19.2.1’ “into “build.gradle” (app) and Click “Sync Now“.
Step 2: Configure realtime database rules for testing
About real time database rules you can read from here
Step 3: Create UserModel Class
data class UserModel( var id: String = "", var name: String = "", var age: Int = 0, var email: String = "" ) { override fun toString(): String { return "UserModel(id='$id', name='$name', age=$age, email='$email')" } }
Step 4: Create layout with 3 edit (name, age and email), 4 button (insert, get, update, delete), 1 recycler view to contain User data
This is my layout.
Step 5:
Write to your database
First initialize databaseReference.
private fun initDatabase() { databaseReference = FirebaseDatabase.getInstance().reference }
Next, get data from EditText and insert to database.
private fun insertUser() { if (edt_name.text.isNullOrEmpty() || edt_age.text.isNullOrEmpty() || edt_email.text.isNullOrEmpty()) { Toast.makeText(this, "Some field are missing.", Toast.LENGTH_SHORT).show() return } //get key val key = databaseReference.child("User").push().key //get user data from edit text val user = UserModel( name = edt_name.text.toString(), age = edt_age.text.toString().toInt(), email = edt_email.text.toString() ) key?.let { user.id = key // Write a data to the database databaseReference.child("User").child(key).setValue(user).addOnSuccessListener { clearText() //get user data from database getUser() //scroll to new item recycler_user.scrollToPosition(recyclerAdapter.userList.size - 1) } .addOnFailureListener { Toast.makeText(this, "Upload Error", Toast.LENGTH_SHORT).show() } } }
Add this code to insert button click event.
btn_insert.setOnClickListener { insertUser() }
After clicking the “Insert” button in your app, data will be send to Firebase immediately.
Read database:
databaseReference.child("User").addValueEventListener(object : ValueEventListener { override fun onCancelled(dataError: DatabaseError) { Toast.makeText(this@DataBaseActivity, "Upload Error", Toast.LENGTH_SHORT).show() } override fun onDataChange(dataSnapshot: DataSnapshot) { //get user list from database val list = dataSnapshot.children.mapNotNull { it.getValue(UserModel::class.java) } list.forEach { Log.i("Users", it.toString()) } //add to recycler view if (list.isNotEmpty()) { recyclerAdapter.userList.clear() recyclerAdapter.userList.addAll(list) recyclerAdapter.notifyDataSetChanged() } } })
Update database:
private fun updateUser() { user?.let { //create new user object val user = UserModel( it.id, edt_name.text.toString(), edt_age.text.toString().toInt(), edt_email.text.toString() ) //update user databaseReference.child("User/${it.id}").setValue(user) } }
Delete database:
private fun deleteUser() { // get user id val query = databaseReference.child("User").orderByChild("id").equalTo(user?.id) query.addListenerForSingleValueEvent(object : ValueEventListener { override fun onDataChange(dataSnapshot: DataSnapshot) { for (user in dataSnapshot.children) { //remove user user.ref.removeValue().addOnSuccessListener { clearText() } } } override fun onCancelled(databaseError: DatabaseError) { Log.e( TAG, "onCancelled", databaseError.toException() ) } }) getUser() }
VI. Reference documents
https://firebase.google.com/docs/guides
https://proandroiddev.com/firebase-android-playground-realtime-database-560d4e18404a
https://www.learnhowtoprogram.com/android/data-persistence/firebase-reading-data-and-event-listeners