— android, firebase, zapier — 5 min read
I want to quickly walk you through how to build a BBC world news aggregator app on Android. The app will make use of the BBC RSS feed to display the news content.
Let me quickly state that I do not work for or represent BBC. The BBC world news is used just as an example, you can plug in your favorite news source as a replacement.
I have created a video lesson on Youtube where I walkthrough every step in details.
The app will be written in the beloved Kotlin. It will be a very simple app which you can easily add additional features on top. I will be making use of two awesome services which are:
Zapier: Zapier is a service that allows you to automate several things. For this project, we will be using Zapier to store any new news item in the BBC news feed in our Firebase database.
Firebase: We will be using the Firebase Realtime Database to save news item in the BBC news feed.
First things first, fire up Android studio and click on New Project. You can give the project any name, but I will be calling it VeryQuickNewsAggregator. Leave all the default options checked and click Next.
While creating the project, make sure you select the option to create a new empty activity. I will be calling that activityMainActivity and it’s going to be the default launcher activity.
Newer versions of Android Studio comes with a tool which you can use to easily integrate Firebase into your application. The tool can be accessed by going to the Tools menu at the top and clicking on Firebase. You should get a screen like this.
There are several really good Firebase services, but for this app, we are only interested in the Realtime Database. Click on Save and retrieve data link under the Realtime Database option. There are two steps you have to take to setup the Firebase database for the app:
Click on the button below Connect your app to Firebase. When the dialog comes up, select an existing project or create a new one.
Click on the button below Add the Realtime Database to your app. It should add the needed dependencies to your build.gradle files.
If you completed the steps listed above, you should get a screen very similar to the one below.
With Firebase setup, let’s add the needed dependencies to our app build.gradle file. We will be adding the following libraries:
RecyclerView: We will be using it to show the list of news items.
Picasso: A simple image loading library which we will be using to load the news thumbnail.
EasyFirebaseList: A library that will help us easily show a list of items from the Firebase database.
FinestWebView: A custom WebView we will be using to display the news item detail.
The app build.gradle file should look like this.
1apply plugin: 'com.android.application'2apply plugin: 'kotlin-android'3apply plugin: 'kotlin-android-extensions'45android {6 compileSdkVersion 267 8 defaultConfig {9 applicationId "com.mobymagic.veryquicknewsaggregator"10 11 minSdkVersion 1412 targetSdkVersion 2613 14 versionCode 115 versionName "1.0"16 17 testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"18 }19 20 buildTypes {21 release {22 minifyEnabled false23 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'24 }25 }26}2728dependencies {29 implementation fileTree(dir: 'libs', include: ['*.jar'])30 implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"31 implementation 'com.android.support:appcompat-v7:26.1.0'32 implementation 'com.android.support:design:26.1.0'33 implementation 'com.android.support:recyclerview-v7:26.1.0'34 implementation 'com.android.support.constraint:constraint-layout:1.0.2'35 implementation 'com.google.firebase:firebase-database:11.6.0'36 implementation 'com.firebaseui:firebase-ui-database:3.1.0'37 implementation 'com.android.support:support-v4:26.1.0'3839 implementation 'com.mobymagic:easyfirebaselist:1.0.2'40 implementation 'com.squareup.picasso:picasso:2.5.2'41 api 'com.thefinestartist:finestwebview:1.2.7'4243 testImplementation 'junit:junit:4.12'44 androidTestImplementation 'com.android.support.test:runner:1.0.1'45 androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'46}4748apply plugin: 'com.google.gms.google-services'
The FinestWebView installation guide states that the FinestWebViewActivity needs to be added to the app AndroidManifest file. Also, we need to request the INTERNET permission to be able to connect to the internet. So our AndroidManifest.xml file will look like this.
1<?xml version="1.0" encoding="utf-8"?>2<manifest xmlns:android="http://schemas.android.com/apk/res/android"3 package="com.mobymagic.veryquicknewsaggregator">45 <uses-permission android:name="android.permission.INTERNET" />6 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />78 <application9 android:allowBackup="true"10 android:icon="@mipmap/ic_launcher"11 android:label="@string/app_name"12 android:roundIcon="@mipmap/ic_launcher_round"13 android:supportsRtl="true"14 android:theme="@style/AppTheme">1516 <activity android:name=".MainActivity">17 <intent-filter>18 <action android:name="android.intent.action.MAIN" />1920 <category android:name="android.intent.category.LAUNCHER" />21 </intent-filter>22 </activity>2324 <activity25 android:name="com.thefinestartist.finestwebview.FinestWebViewActivity"26 android:configChanges="keyboardHidden|orientation|screenSize"27 android:screenOrientation="sensor"28 android:theme="@style/FinestWebViewTheme.Light" />2930 </application>3132</manifest>
The MainActivity will just be hosting a single fragment, so we can modify the activity_main layout file to include the simple FrameLayout below.
1<?xml version="1.0" encoding="utf-8"?>2<FrameLayout3 xmlns:android="http://schemas.android.com/apk/res/android"4 android:id="@+id/newsListFragmentContainer"5 android:layout_width="match_parent"6 android:layout_height="match_parent" />
We will need to create a layout file that shows each news item in a RecyclerView. Create a new layout called item_news . It will just be a very simple horizontal LinearLayout that contains a TextView that shows the news title and an ImageView that displays the news thumbnail.
1<?xml version="1.0" encoding="utf-8"?>2<LinearLayout3 xmlns:android="http://schemas.android.com/apk/res/android"4 android:orientation="horizontal"5 android:layout_width="match_parent"6 android:layout_height="wrap_content"7 android:minHeight="96dp">89 <TextView10 android:id="@+id/newsTitleTextView"11 android:layout_width="0dp"12 android:layout_weight="1"13 android:layout_height="wrap_content"14 android:textAppearance="@style/TextAppearance.AppCompat.Subhead"15 android:textStyle="bold"16 android:padding="16dp" />1718 <ImageView19 android:id="@+id/newsThumbnailImageView"20 android:layout_width="88dp"21 android:layout_height="match_parent"22 android:scaleType="centerCrop"23 android:contentDescription="@null" />2425</LinearLayout>
We can now create a new Fragment that will handle the display of news items. I will name the new Fragment as NewsListFragment, but feel free to use any name here. If you are using the Android studio GUI to create the Fragment, ensure you uncheck all the checkboxes (use the image below as a guide).
Let’s now add the code to show this newly created Fragment in our MainActivity class.
1package com.mobymagic.veryquicknewsaggregator23import android.support.v7.app.AppCompatActivity4import android.os.Bundle56class MainActivity : AppCompatActivity() {78 override fun onCreate(savedInstanceState: Bundle?) {9 super.onCreate(savedInstanceState)10 setContentView(R.layout.activity_main)1112 showNewsFragment()13 }1415 private fun showNewsFragment() {16 val tag = "NewsListFragment"17 val existingFragmentWithTag = supportFragmentManager.findFragmentByTag(tag)1819 if(existingFragmentWithTag == null) {20 supportFragmentManager.beginTransaction()21 .add(R.id.newsListFragmentContainer, NewsListFragment(), tag)22 .commit()23 }24 }2526}
We need to create a model for the news data that will be stored in the Firebase database. We will be using Kotlin Data class which saves us from writing several boilerplate methods like getters and setters.
1package com.mobymagic.veryquicknewsaggregator23data class News(val title: String, val link: String, val description: String, val pubDate: String,4 val thumbnail: String) {56 constructor(): this("", "", "", "", "")78}
Next is to create a RecyclerView.ViewHolder for the news items. Thanks to Kotlin Android Extension, we don’t need to add any findViewById calls here. We only have a very simple bind function that binds the data to the views.
1package com.mobymagic.veryquicknewsaggregator23import android.support.v7.widget.RecyclerView4import android.view.View5import com.squareup.picasso.Picasso6import kotlinx.android.synthetic.main.item_news.view.*78class NewsViewHolder(view: View): RecyclerView.ViewHolder(view) {910 fun bind(model: News) {11 itemView.newsTitleTextView.text = model.title12 Picasso.with(itemView.context).load(model.thumbnail).into(itemView.newsThumbnailImageView)13 }1415}
Finally, let’s add the main ingredient which is the NewsListFragment. We will be making use of the EasyFirebaseList library to easily show a list of items from the Firebase database. The library handles showing progress, empty and error states. The implementation of the NewsListFragment is pretty straightforward.
1package com.mobymagic.veryquicknewsaggregator23import android.support.v4.app.Fragment4import android.support.v7.widget.DividerItemDecoration5import android.support.v7.widget.LinearLayoutManager6import android.support.v7.widget.RecyclerView7import android.view.LayoutInflater8import android.view.ViewGroup9import com.google.firebase.database.DatabaseError10import com.google.firebase.database.FirebaseDatabase11import com.google.firebase.database.Query12import com.mobymagic.easyfirebaselist.EmptyStyle13import com.mobymagic.easyfirebaselist.ErrorStyle14import com.mobymagic.easyfirebaselist.ProgressStyle15import com.mobymagic.easyfirebaselist.database.FirebaseDbListFragment16import com.thefinestartist.finestwebview.FinestWebView1718/**19 * A simple [Fragment] subclass.20 */21class NewsListFragment : FirebaseDbListFragment<News, NewsViewHolder>() {2223 override fun getDataClass(): Class<News> {24 return News::class.java25 }2627 override fun getEmptyStyle(): EmptyStyle {28 return EmptyStyle(R.drawable.ic_error_view_cloud, "No news yet in database")29 }3031 override fun getErrorStyle(error: DatabaseError): ErrorStyle {32 return ErrorStyle(R.drawable.ic_error_view_cloud, "An error occurred while fetching news")33 }3435 override fun getProgressStyle(): ProgressStyle {36 return ProgressStyle("Loading...")37 }3839 override fun getQuery(): Query {40 return FirebaseDatabase.getInstance().reference.child("news").limitToLast(100)41 }4243 override fun onBindViewHolder(viewHolder: NewsViewHolder, key: String, model: News) {44 viewHolder.bind(model)45 }4647 override fun onCreateViewHolder(inflater: LayoutInflater, viewGroup: ViewGroup): NewsViewHolder {48 val view = inflater.inflate(R.layout.item_news, viewGroup, false)49 return NewsViewHolder(view)50 }5152 override fun onItemClicked(viewHolder: NewsViewHolder, key: String, model: News) {53 FinestWebView.Builder(activity).show(model.link)54 }5556 override fun setupRecyclerView(recyclerView: RecyclerView) {57 recyclerView.addItemDecoration(DividerItemDecoration(activity, DividerItemDecoration.VERTICAL))58 recyclerView.layoutManager = LinearLayoutManager(activity)59 }60 61}
The last step is to use Zapier to automate the reading and saving of the BBC world news RSS feed items to the Firebase database.
We will need to create a new ZAP (task) on Zapier. Zaps are automations created using one Trigger and one Action. So tasks are made of two important components:
Trigger: A Trigger is any event that sets your Zap in motion. Some examples of Triggers include a new favorited Tweet on Twitter, a new email in Gmail, or a new note in Evernote.
Action: An Action is an event that’s completed in a second app automatically. Some examples of Actions include appending text to a note in Evernote, adding a new spreadsheet row in a Google Doc, or creating a new card in Trello.
If you are new to Zapier, you can easily create a new account. After login, click on Make A Zap button (It’s located at the top with an orange background). When the page loads up, search for the RSS app and select it.
After selecting the RSS app, click on the continue button. Select the single option that shows up when the next page loads up and click on Continue again.
The next screen is where you specify the RSS feed URL. We will be using the BBC world news RSS feed URL here. Leave every other field unchanged and click on Continue
The final step for the RSS feed trigger is to test it to ensure Zapier can actually access the RSS feed. After successfully testing it, click on Continue to create a new Action.
We want to insert each new news item into the Firebase database. So for the action, search for Firebase, select it and click on Continue.
The next screen will prompt you to select an action. We will select the Create Child Record action and click on Continue.
In the next screen, you will have to setup the Firebase child record. Use the image below as a guide or you can watch the video lesson (included at the top of this post).
After setting up the Firebase child record, click on Continue. The next and final step will be to test the Firebase database. After doing that you can click on Finish which will create a new ZAP in your Zapier account. Don’t forget to give your ZAP a name and switch it ON.
You can now install the app on an emulator or real device and run it. It should display the data currently in the Firebase Realtime Database. As Zapier adds more items to the database, it will get automatically updated on the app.
So, that’s it. You have successfully created a news aggregator app. If you have any question, please leave a comment below and I will reply as soon as possible. You can view the project Repository on Github.