Showing posts with label Tutorial. Show all posts
Showing posts with label Tutorial. Show all posts

25 May 2016

Firebase Tutorial For Android Developers


I've sadly never had the chance to use Firebase in a production app. After Google talked about it so much at this year's IO I though it was about time I had a play and created a tutorial.

Firebase is primarily a real time database that makes data storage simple and easy. In the last few years it's been expanded to be an incredible fleet of tools that Android, iOS and Web developers can make use of.

The Firebase database is an inspired solution to data storage and syncing. The Firebase db is a NoSQL, cloud hosted database that allows for fast and easy sync across different devices. No more clumsy sync adapters or troublesome push notifications, Firebase handles all this for you with a simple API.

Also included in the suite is analytics, crash reporting, file storage, authentication, remote config and more.

I know I'm beginning to sound a bit like a marketing rep, but I really must say I'm flawed by how awesome Firebase is. The cloud sync database is really simple to set-up and it works incredibly well.

OK let's get into a tutorial. I wanted to link my app to Firebase and create a cloud db. Sounds easy! First you will be required to have a Google account, then we goto Firebase and create a new project:

https://console.firebase.google.com/

Now you have a Firebase app. Next we need to add it to Android, the wizard walks you through this process with a lovely little Material designed guide. You'll need the package name of your app and then to make some gradle and config changes.

Now we need to disable authentication. If you goto the Firebase console and click database on the left hand side you should see an empty data set. In the tabs above click on rules and change the json to match this:

{
  "rules": {
    ".read": true,
    ".write": true
  }
}

This basically disables all authentication giving anyone write and read access. For a real application you'd want to set-up proper user role based access, but for this tutorial will just turn authentication off.

Next you'll need to setup your Android project. You should already have the json config file and the gradle additions. Now you need to add the database gradle dependancy:

compile 'com.google.firebase:firebase-database:9.0.0'
That's it, you're pretty much ready to go. However there are a few important db constraints to get your head around before you launch your new app.

Data in Firebase is all JSON but it does support saving objects, lists, maps as well as simple data types such as strings, booleans, doubles etc. It seems to me largely based around a key value pair type of system. You put a value with it's corresponding key to Firebase and it syncs it. Then use the same key to retrieve that data.

SetValue

SetValue is an assignment method. At first I thought you could use it to create new db entries, but that is not the case. Instead you call

FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("message");

myRef.setValue("Hello, World!");

This creates a key value pair with the key "message" and the value "Hello, World!". If you call setValue again on that key, the value is overwritten, a new pair is not created in this way.

ValueEventListener

The ValueEventListener gives you the ability to receive a callback when your data changes. This is useful when you create your UI so you can receive updates whenever the data changes. No more db listeners or broadcasts.

public void onDataChange(DataSnapshot dataSnapshot)

All you need to do is attatch the listener

myRef.addValueEventListener(this);

Push

Push allows create a list of data. Using this method generates a unique key instead of forcing you to create a new key for every object.

Save Data

Here's how I added a list of simple objects. Player is just a simple pojo. We use push to create a new child of the DB_KEY_PLAYERS type. We then get the key of that new child.
Using that key we can now update it's data. The second param to setValue is a callback so we can update the UI when the data has been updated successfully.

FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myplayers = database.getReference(DB_KEY_PLAYERS);

//Get key for a new player
String key = myplayers.push().getKey();
Player player = new Player(playername);
//set value of new player
myplayers.child(key).setValue(player, ActivityAddPlayer.this);


That's it, you should now have a working cloud synch'd database. You can now add analytics and crash reporting as well, super simple and very well designed. I really hope I get to put it into practice in a live app sometime soon.

This content is copyright and owned by https://webdeveloperpadawan.blogspot.com/

31 May 2015

Android Design Support Library Collapsing Toolbar


Following Google IO I'm always that much more inspired to try a few new things with Android.
Shortly after IO I noticed this new post on the devlopers blog:
http://android-developers.blogspot.co.uk/2015/05/android-design-support-library.html

I immediately loved the CollapsingToolbarLayout as I've had to make something similar myself and never quite got it perfect. The fact that Google are releasing quick and easy ways to implement these design elements is absolutely fantastic. Long may it continue!

When I saw Ian Lake's post on this collapsing toolbar I was super keen to give them a go:
https://plus.google.com/+IanLake/posts/QGR5XNcPPeG

I didn't get especially far until this example from Chris Banes:
https://github.com/chrisbanes/cheesesquare

I decided (as usual) to make mine as simple as possible, stripping out as much of the superfluous stuff as I could.

First we need the support and design libraries:
    compile 'com.android.support:appcompat-v7:22.2.0'
    compile 'com.android.support:design:22.2.0'
    compile 'com.android.support:recyclerview-v7:22.2.0'

First thing we'll do is the xml for our main activity
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:layout_scrollFlags="scroll|enterAlways" />

        <TextView
            android:text="@string/hello_world"
            android:padding="20dp"
            android:layout_width="match_parent"
            android:textColor="#00FF00"
            android:layout_height="wrap_content"/>
    </android.support.design.widget.AppBarLayout>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/activity_main_listview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>

The important bit here is the AppBarLayout which contains the Toolbar and a TextView which I want to hover over the top of the listview.

Second you'll notice we're using a RecyclerView which is new to me but looks to be more powerful than Listview.

Our ActivityMain just passes an ArrayList of Strings too the Recycler View
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.activity_main_listview);
recyclerView.setLayoutManager(new LinearLayoutManager(recyclerView.getContext()));
recyclerView.setAdapter(new MyRecyclerView(this, players));

Oh and of course don't forget to make sure your Activity uses AppCompatActivity and your manifest has a theme which overrides or implements Theme.AppCompat.Light.NoActionBar
You'll need the MyRecylcerView class but that's fairly boring and I borrowed most of it from Chris Banes, so I'll let you look at that in the git repo (bottom).

Now we need to look at the detail page where we use CollapsingToolbarLayout. First the xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="400dp"
        android:theme="@style/ActionBarPopupThemeOverlay"
        android:fitsSystemWindows="true">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            android:fitsSystemWindows="true"
            app:contentScrim="@color/colorPrimary"
            app:expandedTitleMarginStart="48dp"
            app:expandedTitleMarginEnd="64dp">

            <ImageView
                android:id="@+id/backdrop"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop"
                android:fitsSystemWindows="true"
                app:layout_collapseMode="parallax" />

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:theme="@style/ActionBarPopupThemeOverlay"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                app:layout_collapseMode="pin" />
        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>

    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:paddingTop="24dp">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="20dp"
                android:text="All your base are belong to me." />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="20dp"
                android:text="All your base are belong to me." />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="20dp"
                android:text="All your base are belong to me." />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="20dp"
                android:text="All your base are belong to me." />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="20dp"
                android:text="All your base are belong to me." />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="20dp"
                android:text="All your base are belong to me." />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="20dp"
                android:text="All your base are belong to me." />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="20dp"
                android:text="All your base are belong to me." />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:padding="20dp"
                android:textColor="@color/colorAccent"
                android:text="All your base are belong to me." />
        </LinearLayout>
    </android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>

Here we use a NestedScrollView instead of a RecyclerView, hence the big list of TextViews

The Activity is even simpler here, we read in the extra and setup the toolbar title and background image, then setup the action bar so it's an up navaigation and set the title:
final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);

CollapsingToolbarLayout collapsingToolbar = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
collapsingToolbar.setTitle(muppetName);

That's basically it, a few new concepts and tools here but its super easy.

Here's the GitHub repo of all of this:
https://github.com/jimbo1299/androiddesigntest