a realtime infrastructure for android apps: firebase may be what you need..and even more!

Post on 16-Apr-2017

1.312 Views

Category:

Software

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Are you looking for a realtime infrastructure behind your mobile app?

Well, Firebase may be what you need..and even more!

DroidconIT2016 – Alessandro Martellucci

I’m Alessandro Martellucci

alex.martellucci@gmail.com

martellux

+AlessandroMartellucci

@martellux

DroidconIT2016 – Alessandro Martellucci

Open Reply

•  Reply is a leading IT Services Company, with offices in Italy, Germany, UK, Benelux, USA, Brazil, France and Poland.

•  Open Reply is the company of Reply Group focused on open source software, multichannel solutions and mobile applications.

•  From Rome to Milan, our team is based on a young team of over 40 engineers 100% focused on mobile development (iOS, Android & Windows Phone).

•  We are specialised in broadcasting, banking, Android OS Customisation, IoT and M2M.

We are hiring! Contact us at jobs@reply.eu

DroidconIT2016 – Alessandro Martellucci

Lifecycle 0.2

A binder which let you manage async operations against Android components lifecycle •  Seamless execution async-rotation-response •  Easily integration with third-party library •  No crashes after Activity/Fragment rotation •  Fragment transaction management

martellux/Lifecycle com.martellux:lifecycle:0.2.0

DroidconIT2016 – Alessandro Martellucci

Android Programmazione Avanzata

•  Multi-screen and multi device development

•  Functional Programming with RxJava

•  Testing & Code Mantainance

•  Android Wear

•  Bluetooth Classic & Low Energy

•  Google Cast and Chromecast

DroidconIT2016 – Alessandro Martellucci

Agenda

1.  What is Firebase 2.  NoSQL JSON database 3.  Demo 4.  Android integration 5.  Working with data 6.  Working offline 7.  FirebaseUI binding 8.  Rules management 9.  User authentication 10. Pricing

DroidconIT2016 – Alessandro Martellucci

What is Firebase

•  MBaaS

•  Data synchronization •  Hosting (static assets, Node.js)

•  Authentication (Google, Facebook, Email & Password, Anonymous)

•  Realtime database (JSON)

DroidconIT2016 – Alessandro Martellucci

NoSQL Database

•  SQL & RDBMS

•  JSON •  web format •  agile •  structure •  friendliness

•  Drawbacks •  navigational query •  structure

DroidconIT2016 – Alessandro Martellucci

Firebase JSON

{ “event-name”:”Droidcon Italy”, “location”: { “latitude”:22, “longitude”:22 }, “events”: [ {“name”: “Are you looking for a realtime…”, “speaker”: “Alessandro Martellucci”, “room”: “Sala Parigi”, “time”: 000000 }, … ] }

JSON

DroidconIT2016 – Alessandro Martellucci

Firebase Web Console

DroidconIT2016 – Alessandro Martellucci

Firebase Vulcan Console

DroidconIT2016 – Alessandro Martellucci

DroidconIT 2016 FirebaseDemo

•  We’re going live 1.  Download app 2.  Hit your colour 3.  Be patient

DroidconIT2016 – Alessandro Martellucci

Source code at https://github.com/martellux/

Android integration

•  Account •  Sign with Google

•  Dependecies •  Right click -> Project Structure -> Cloud -> Firebase

•  Reference •  Navigation path

DroidconIT2016 – Alessandro Martellucci

Firebase setup (1/2)

dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.firebase:firebase-client-android:2.5.1+’ } android { packagingOptions { exclude 'META-INF/LICENSE’ exclude 'META-INF/LICENSE-FIREBASE.txt’ exclude 'META-INF/NOTICE’ } }

Configura.on

DroidconIT2016 – Alessandro Martellucci

Firebase setup (2/2)

public class ApplicationInstance extends Application { @Override public void onCreate() { super.onCreate(); Firebase.setAndroidContext(this); } }

Applica.on

DroidconIT2016 – Alessandro Martellucci

public class MainPresenter extends Presenter { private Firebase mFirebaseRef = new Firebase(“https://droidconit2016-demo.firebaseio.com”); }

Presenter

Reading data

•  Callbacks

•  Read Type •  Value •  Child

•  Firebase Listener •  ValueEventListener •  ChildEventListener (added, removed, changed)

DroidconIT2016 – Alessandro Martellucci

Read value changes

Firebase mFirebaseRef = new Firebase(“https://droidconit2016-demo.firebaseio.com”); mFirebaseRef.child(“data”).addValueEventListener(new ValueEventListener() { @Override public void onDataChange(DataSnapshot snapshot) { Map<String, Object> value = snapshot.getValue(Map.class); //or MyBean myBean = snapshot.getValue(MyBean.class); } @Override public void onCancelled(FirebaseError firebaseError) { Log.e(TAG, "The read failed: " + firebaseError.getMessage()); } });

ValueEventListener

DroidconIT2016 – Alessandro Martellucci

Read new child

Firebase mFirebaseRef = new Firebase(“https://droidconit2016-demo.firebaseio.com/data”); mFirebaseRef.addChildEventListener(new ChildEventListener() {

@Override public void onChildAdded(DataSnapshot snapshot, String previousChildKey) {

MyBean myBean = snapshot.getValue(MyBean.class); String foo = myBean.getFoo(); } @Override public void onCancelled(FirebaseError firebaseError) { Log.e(TAG, "The read failed: " + firebaseError.getMessage()); } });

ChildEventListener

DroidconIT2016 – Alessandro Martellucci

Read child updates

Firebase mFirebaseRef = new Firebase(“https://droidconit2016-demo.firebaseio.com/data”); mFirebaseRef.addChildEventListener(new ChildEventListener() {

@Override public void onChildChanged(DataSnapshot snapshot, String previousChildKey) {

MyBean myBean = snapshot.getValue(MyBean.class);

Log.d(TAG, ”Prop foo has been updated to: " + myBean.getFoo()); } @Override public void onCancelled(FirebaseError firebaseError) { Log.e(TAG, "The read failed: " + firebaseError.getMessage()); } });

ChildEventListener

DroidconIT2016 – Alessandro Martellucci

Read removed child

Firebase mFirebaseRef = new Firebase(“https://droidconit2016-demo.firebaseio.com/data”); mFirebaseRef.addChildEventListener(new ChildEventListener() {

@Override public void onChildRemoved(DataSnapshot snapshot) {

MyBean myBean = snapshot.getValue(MyBean.class);

System.out.println(”This entry has been removed: " + myBean.toString()); } @Override public void onCancelled(FirebaseError firebaseError) { System.out.println("The read failed: " + firebaseError.getMessage()); } });

ChildEventListener

DroidconIT2016 – Alessandro Martellucci

Saving Data

•  Non-concurrent •  Insert •  Update

•  Concurrent •  IDs generation •  Transaction

DroidconIT2016 – Alessandro Martellucci

Write or replace data (1/2)

{ …, status: { connectedUsers: 10, ... }, ... }

Onlineusers

DroidconIT2016 – Alessandro Martellucci

Firebase mFirebaseRef = new Firebase(“https://droidconit2016-demo.firebaseio.com”); int connectedUsers = countConnectedUsers(); mFirebaseRef.child(“status/connectedUsers”).setValue(connectedUsers);

1)Naviga.ngbysubnodes

Write or replace data (2/2)

Firebase mFirebaseRef = new Firebase(“https://droidconit2016-demo.firebaseio.com/status”);

int connectedUsers = countConnectedUsers();

mFirebaseRef.child(“connectedUsers”).setValue(connectedUsers);

2)Naviga.ngdirecttonode

DroidconIT2016 – Alessandro Martellucci

Firebase mFirebaseRef = new Firebase(“https://droidconit2016-demo.firebaseio.com/status”);

Map<String, String> statusMap = new HashMap<String, String>();

statusMap.put(“connectedUsers”, String.valueOf(countConnectedUsers());

mFirebaseRef.setValue(statusMap);

3)UsingMap

Overwrite & delete

JSONnode

DroidconIT2016 – Alessandro Martellucci

{ “status”:{ “connectedUsers”:1, “startTime”:1456426772000, “endTime”:1456426772000 } }

{ “status”:{ “connectedUsers”:1 } }

Firebase mFirebaseRef = new Firebase(“https://droidconit2016-demo.firebaseio.com/status”); Map<String, String> statusMap = new HashMap<String, String>();

statusMap.put(“connectedUsers”, String.valueOf(countConnectedUsers());

mFirebaseRef.setValue(statusMap);

JavaCode

Update children

Firebase mFirebaseRef = new Firebase(“https://droidconit2016-demo.firebaseio.com/status”); Map<String, String> statusMap = new HashMap<String, String>(); statusMap.put(“connectedUsers”, String.valueOf(countConnectedUsers()); mFirebaseRef.updateChildren(statusMap);

1)Upda.ngnodes

DroidconIT2016 – Alessandro Martellucci

Firebase mFirebaseRef = new Firebase(“https://droidconit2016-demo.firebaseio.com”); Map<String, String> statusMap = new HashMap<String, String>(); statusMap.put(“status/connectedUsers”, String.valueOf(countConnectedUsers());

mFirebaseRef.updateChildren(statusMap);

2)Upda.ngsubnodes

Concurrent-indipendent insert

Firebase mFirebaseRef = new Firebase(“https://droidconit2016-demo.firebaseio.com”); Firebase dataChildRef = mFirebaseRef.child(“data”); Firebase newChildRef = dataChildRef.push();

Map<String, Object> colorMap = new HahsMap<String, Object>(); colorMap.put(“red”, “242”); colorMap.put(“green”, “10”); colorMap.put(“blue”, “22”); newChildRef .setValue(colorMap);

JavaCode

DroidconIT2016 – Alessandro Martellucci

Concurrent-dipendent insert

Firebase mFirebaseRef = new Firebase(“https://droidconit2016-demo.firebaseio.com/data”); newChildRef.runTransaction(new Transaction.Handler() { @Override public Transaction.Result doTransaction(MutableData currentData) { if((currentData.getValue() == null) { currentData.setValue(1); } else { currentData.setValue((Long) currentData.getValue() + 1); } return Transaction.success(currentData); } @Override public void onComplete(FirebaseError error, boolean committed, DataSnapshot currentData) { … } });

JavaCode

DroidconIT2016 – Alessandro Martellucci

Working offline

•  Works offline

•  Seamless experience

•  Auto synchronization

DroidconIT2016 – Alessandro Martellucci

User authentication

DroidconIT2016 – Alessandro Martellucci

•  User identification •  Email & password login

•  Easy integration •  Facebook, GitHub, Google and Twitter

•  Session management •  Single session •  Custom token

FirebaseUI - Authentication

DroidconIT2016 – Alessandro Martellucci

1.  Add SDK dependencies 2.  Add Facebook/Twitter/Google keys to

strings.xml 3.  Change our AndroidManifest.xml 4.  Inherit from FirebaseLoginBaseActivity 5.  Enable authentication providers 6.  Call showFirebaseLoginDialog();

Facebook authentication

DroidconIT2016 – Alessandro Martellucci

Firebase mFirebaseRef = new Firebase(“https://droidconit2016-demo.firebaseio.com/data”); mFirebaseRef .addAuthStateListener(new Firebase.AuthStateListener() { @Override public void onAuthStateChanged(AuthData authData) { if (authData != null) { // user is logged in Map<String, String> map = new HashMap<String, String>(); map.put("provider", authData.getProvider()); if(authData.getProviderData().containsKey("displayName")) { map.put("displayName", authData.getProviderData().get("displayName").toString()); } ref.child("users").child(authData.getUid()).setValue(map); } else { // user is not logged in } } });

Authen.ca.on

Rules management (1/2)

DroidconIT2016 – Alessandro Martellucci

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

Basicrules

•  JavaScript-like

•  Node permissions •  Node validations

Rules management (2/2)

DroidconIT2016 – Alessandro Martellucci

{ “status”: { “schedule”: { “startTime”: 123456670292, … } } }

startTimenode

{ "rules": { "status": { "schedule": { "startTime": { // readable ".read": true, // data written must be a number ".validate": "newData.isNumber()”, // write authorization ".write": "$user_id === auth.uid” }}}}}

RulesforstartTimenode

FirebaseUI

DroidconIT2016 – Alessandro Martellucci

•  Open source library •  iOS support

•  Authentication

•  built-in dialog •  List binding

•  ListView •  RecyclerView

FirebaseUI – ListView

DroidconIT2016 – Alessandro Martellucci

@Override protected void onCreate(Bundle savedInstanceState) { … ListView messagesView = (ListView) findViewById(R.id.messages_list); mAdapter = new FirebaseListAdapter<MyBean>(this, MyBean.class, R.layout.my_list_item, mFirebaseRef) { @Override protected void populateView(View view, MyBean myBean, int position) { ((TextView)view.findViewById(android.R.id.text1)).setText(myBean.getFoo()); } }; messagesView.setAdapter(mAdapter); }

Adapter

FirebaseUI – RecyclerView

DroidconIT2016 – Alessandro Martellucci

@Override protected void onCreate(Bundle savedInstanceState) { … RecyclerView recycler = (RecyclerView) findViewById(R.id.messages_recycler); recycler.setHasFixedSize(true); recycler.setLayoutManager(new LinearLayoutManager(this)); mAdapter = new FirebaseRecyclerAdapter<MyBean, MyBeanViewHolder>(MyBean.class, R.layout.my_line_list_item, MyBeanViewHolder.class, mFirebaseRef) { @Override public void populateViewHolder(MyBeanViewHolder myBeanViewHolder, MyBean myBean, int position) { myBeanViewHolder.nameText.setText(myBean.getFoo()); } }; recycler.setAdapter(mAdapter); }

Adapter

Pricing

DroidconIT2016 – Alessandro Martellucci

FREE(0$forever)

SPARK(5$month)

… INFERNO(1499$month)

DBconnec.ons 100 100 … UNLIMITED

DBstorage 1GB 1GB … 300GB

DBtransfer 10GB 10GB … 1.5TB

PrivateBackups NO NO … YES

Authen.ca.on UNLIMITEDUSERS

UNLIMITEDUSERS … UNLIMITED

USERS

Hos.ngStorage 1GB 1GB … 10GB

Hos.ngTransfer 100GB 100GB … 1TB

CustomDomain NO YES … YES

Resources

•  BLOG: https://www.firebase.com/blog

•  Twitter: @firebase

•  Facebook: Firebase

•  Google Plus: Firebase

•  Official: http://www.firebase.com

•  Github: https://github.com/firebase

•  YouTube: Firecast: Firebase Screencast

DroidconIT2016 – Alessandro Martellucci

THANK YOU ALL

DroidconIT2016 – Alessandro Martellucci

top related