Skip to content
Elvis Chidera

Build A BBC World News Aggregator App In 35 Minutes — Building Android App Series

android, firebase, zapier5 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.

Final product

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:

  1. 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.

  2. Firebase: We will be using the Firebase Realtime Database to save news item in the BBC news feed.

image1

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.

image2

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.

image3

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.

image4

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:

  1. Click on the button below Connect your app to Firebase. When the dialog comes up, select an existing project or create a new one.

  2. 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.

image5

With Firebase setup, let’s add the needed dependencies to our app build.gradle file. We will be adding the following libraries:

  1. RecyclerView: We will be using it to show the list of news items.

  2. Picasso: A simple image loading library which we will be using to load the news thumbnail.

  3. EasyFirebaseList: A library that will help us easily show a list of items from the Firebase database.

  4. FinestWebView: A custom WebView we will be using to display the news item detail.

The app build.gradle file should look like this.

build.gradle
1apply plugin: 'com.android.application'
2apply plugin: 'kotlin-android'
3apply plugin: 'kotlin-android-extensions'
4
5android {
6 compileSdkVersion 26
7
8 defaultConfig {
9 applicationId "com.mobymagic.veryquicknewsaggregator"
10
11 minSdkVersion 14
12 targetSdkVersion 26
13
14 versionCode 1
15 versionName "1.0"
16
17 testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
18 }
19
20 buildTypes {
21 release {
22 minifyEnabled false
23 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
24 }
25 }
26}
27
28dependencies {
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'
38
39 implementation 'com.mobymagic:easyfirebaselist:1.0.2'
40 implementation 'com.squareup.picasso:picasso:2.5.2'
41 api 'com.thefinestartist:finestwebview:1.2.7'
42
43 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}
47
48apply 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.

AndroidManifest.xml
1<?xml version="1.0" encoding="utf-8"?>
2<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3 package="com.mobymagic.veryquicknewsaggregator">
4
5 <uses-permission android:name="android.permission.INTERNET" />
6 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
7
8 <application
9 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">
15
16 <activity android:name=".MainActivity">
17 <intent-filter>
18 <action android:name="android.intent.action.MAIN" />
19
20 <category android:name="android.intent.category.LAUNCHER" />
21 </intent-filter>
22 </activity>
23
24 <activity
25 android:name="com.thefinestartist.finestwebview.FinestWebViewActivity"
26 android:configChanges="keyboardHidden|orientation|screenSize"
27 android:screenOrientation="sensor"
28 android:theme="@style/FinestWebViewTheme.Light" />
29
30 </application>
31
32</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.

activity_main.xml
1<?xml version="1.0" encoding="utf-8"?>
2<FrameLayout
3 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.

item_news.xml
1<?xml version="1.0" encoding="utf-8"?>
2<LinearLayout
3 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">
8
9 <TextView
10 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" />
17
18 <ImageView
19 android:id="@+id/newsThumbnailImageView"
20 android:layout_width="88dp"
21 android:layout_height="match_parent"
22 android:scaleType="centerCrop"
23 android:contentDescription="@null" />
24
25</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).

image6

Let’s now add the code to show this newly created Fragment in our MainActivity class.

MainActivity.kt
1package com.mobymagic.veryquicknewsaggregator
2
3import android.support.v7.app.AppCompatActivity
4import android.os.Bundle
5
6class MainActivity : AppCompatActivity() {
7
8 override fun onCreate(savedInstanceState: Bundle?) {
9 super.onCreate(savedInstanceState)
10 setContentView(R.layout.activity_main)
11
12 showNewsFragment()
13 }
14
15 private fun showNewsFragment() {
16 val tag = "NewsListFragment"
17 val existingFragmentWithTag = supportFragmentManager.findFragmentByTag(tag)
18
19 if(existingFragmentWithTag == null) {
20 supportFragmentManager.beginTransaction()
21 .add(R.id.newsListFragmentContainer, NewsListFragment(), tag)
22 .commit()
23 }
24 }
25
26}

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.

News.kt
1package com.mobymagic.veryquicknewsaggregator
2
3data class News(val title: String, val link: String, val description: String, val pubDate: String,
4 val thumbnail: String) {
5
6 constructor(): this("", "", "", "", "")
7
8}

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.

NewsViewHolder.kt
1package com.mobymagic.veryquicknewsaggregator
2
3import android.support.v7.widget.RecyclerView
4import android.view.View
5import com.squareup.picasso.Picasso
6import kotlinx.android.synthetic.main.item_news.view.*
7
8class NewsViewHolder(view: View): RecyclerView.ViewHolder(view) {
9
10 fun bind(model: News) {
11 itemView.newsTitleTextView.text = model.title
12 Picasso.with(itemView.context).load(model.thumbnail).into(itemView.newsThumbnailImageView)
13 }
14
15}

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.

NewsListFragment.kt
1package com.mobymagic.veryquicknewsaggregator
2
3import android.support.v4.app.Fragment
4import android.support.v7.widget.DividerItemDecoration
5import android.support.v7.widget.LinearLayoutManager
6import android.support.v7.widget.RecyclerView
7import android.view.LayoutInflater
8import android.view.ViewGroup
9import com.google.firebase.database.DatabaseError
10import com.google.firebase.database.FirebaseDatabase
11import com.google.firebase.database.Query
12import com.mobymagic.easyfirebaselist.EmptyStyle
13import com.mobymagic.easyfirebaselist.ErrorStyle
14import com.mobymagic.easyfirebaselist.ProgressStyle
15import com.mobymagic.easyfirebaselist.database.FirebaseDbListFragment
16import com.thefinestartist.finestwebview.FinestWebView
17
18/**
19 * A simple [Fragment] subclass.
20 */
21class NewsListFragment : FirebaseDbListFragment<News, NewsViewHolder>() {
22
23 override fun getDataClass(): Class<News> {
24 return News::class.java
25 }
26
27 override fun getEmptyStyle(): EmptyStyle {
28 return EmptyStyle(R.drawable.ic_error_view_cloud, "No news yet in database")
29 }
30
31 override fun getErrorStyle(error: DatabaseError): ErrorStyle {
32 return ErrorStyle(R.drawable.ic_error_view_cloud, "An error occurred while fetching news")
33 }
34
35 override fun getProgressStyle(): ProgressStyle {
36 return ProgressStyle("Loading...")
37 }
38
39 override fun getQuery(): Query {
40 return FirebaseDatabase.getInstance().reference.child("news").limitToLast(100)
41 }
42
43 override fun onBindViewHolder(viewHolder: NewsViewHolder, key: String, model: News) {
44 viewHolder.bind(model)
45 }
46
47 override fun onCreateViewHolder(inflater: LayoutInflater, viewGroup: ViewGroup): NewsViewHolder {
48 val view = inflater.inflate(R.layout.item_news, viewGroup, false)
49 return NewsViewHolder(view)
50 }
51
52 override fun onItemClicked(viewHolder: NewsViewHolder, key: String, model: News) {
53 FinestWebView.Builder(activity).show(model.link)
54 }
55
56 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:

  1. 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.

  2. 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.

image7

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.

image8

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

image9

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.

image10

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.

image11

The next screen will prompt you to select an action. We will select the Create Child Record action and click on Continue.

image12

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).

image13

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.

image14

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.

© 2020 by Elvis Chidera. All rights reserved.