Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Adrián Catalan: Firebase & Android, a Real-Time...

Realm
July 29, 2016

Adrián Catalan: Firebase & Android, a Real-Time Match Synced in Heaven

Firebase provides a real-time database and handles authentication among many interesting features. It allows developers to focus on building amazing apps and not worrying about the backend. Through this talk, we will review how to make the most out of this tools in Android, from the first steps, all the way to building an app that synchronize data and authenticates with several major providers, using Firebase.

Realm

July 29, 2016
Tweet

More Decks by Realm

Other Decks in Technology

Transcript

  1. <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.bitandik.labs.simplefirebase" > <uses-permission android:name="android.permission.INTERNET" />

    <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> https://github.com/ykro/firebase-minimun-example/blob/master/app/src/main/AndroidManifest.xml AndroidManifest.xml
  2. https://github.com/ykro/firebase-minimun-example/blob/master/app/src/main/AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.bitandik.labs.simplefirebase" > <uses-permission android:name="android.permission.INTERNET"

    /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> AndroidManifest.xml
  3. https://github.com/ykro/firebase-minimun-example/blob/master/build.gradle buildscript { repositories { jcenter() } dependencies { classpath

    'com.android.tools.build:gradle:2.2.0-alpha3' classpath 'com.google.gms:google-services:3.0.0' } } build.gradle
  4. https://github.com/ykro/firebase-minimun-example/blob/master/build.gradle buildscript { repositories { jcenter() } dependencies { classpath

    'com.android.tools.build:gradle:2.2.0-alpha3' classpath 'com.google.gms:google-services:3.0.0' } } build.gradle
  5. dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile

    'com.android.support:appcompat-v7:23.4.0' compile 'com.google.firebase:firebase-database:9.0.2' } apply plugin: 'com.google.gms.google-services' https://github.com/ykro/firebase-minimun-example/blob/master/app/build.gradle app/build.gradle
  6. dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile

    'com.android.support:appcompat-v7:23.4.0' compile 'com.google.firebase:firebase-database:9.0.2' } apply plugin: 'com.google.gms.google-services' https://github.com/ykro/firebase-minimun-example/blob/master/app/build.gradle app/build.gradle
  7. <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin"

    android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/editText" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/txtBtnSend" android:id="@+id/button" android:layout_below="@+id/editText" android:layout_centerHorizontal="true" /> </RelativeLayout> https://github.com/ykro/firebase-minimun-example/blob/master/app/src/main/res/layout/activity_main.xml layout/activity_main.xml
  8. public class MainActivity extends AppCompatActivity { private FirebaseDatabase database; private

    String MESSAGE_CHILD = "message"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); database = FirebaseDatabase.getInstance(); DatabaseReference messageReference = database.getReference().child(MESSAGE_CHILD); messageReference.setValue("Hello, World!"); ... } } https://github.com/ykro/firebase-minimun-example/blob/master/app/src/main/java/com/bitandik/labs/simplefirebase/MainActivity.java MainActivity.java
  9. public class MainActivity extends AppCompatActivity { private FirebaseDatabase database; private

    String MESSAGE_CHILD = "message"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); database = FirebaseDatabase.getInstance(); DatabaseReference messageReference = database.getReference().child(MESSAGE_CHILD); messageReference.setValue("Hello, World!"); ... } } https://github.com/ykro/firebase-minimun-example/blob/master/app/src/main/java/com/bitandik/labs/simplefirebase/MainActivity.java MainActivity.java
  10. public class MainActivity extends AppCompatActivity { private FirebaseDatabase database; private

    String MESSAGE_CHILD = "message"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); database = FirebaseDatabase.getInstance(); DatabaseReference messageReference = database.getReference().child(MESSAGE_CHILD); messageReference.setValue("Hello, World!"); ... } } https://github.com/ykro/firebase-minimun-example/blob/master/app/src/main/java/com/bitandik/labs/simplefirebase/MainActivity.java MainActivity.java
  11. public class MainActivity extends AppCompatActivity { private FirebaseDatabase database; private

    String WORDS_CHILD = "words"; @Override protected void onCreate(Bundle savedInstanceState) { ... final Button btn = (Button)findViewById(R.id.button); final EditText editText = (EditText)findViewById(R.id.editText); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { DatabaseReference newElementReference = database.getReference().child(WORDS_CHILD).push(); newElementReference.setValue(editText.getText().toString()); editText.setText(""); } }); } } https://github.com/ykro/firebase-minimun-example/blob/master/app/src/main/java/com/bitandik/labs/simplefirebase/MainActivity.java MainActivity.java
  12. public class MainActivity extends AppCompatActivity { private FirebaseDatabase database; private

    String WORDS_CHILD = "words"; @Override protected void onCreate(Bundle savedInstanceState) { ... final Button btn = (Button)findViewById(R.id.button); final EditText editText = (EditText)findViewById(R.id.editText); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { DatabaseReference newElementReference = database.getReference().child(WORDS_CHILD).push(); newElementReference.setValue(editText.getText().toString()); editText.setText(""); } }); } } https://github.com/ykro/firebase-minimun-example/blob/master/app/src/main/java/com/bitandik/labs/simplefirebase/MainActivity.java MainActivity.java
  13. public class MainActivity extends AppCompatActivity { private FirebaseDatabase database; private

    String WORDS_CHILD = "words"; @Override protected void onCreate(Bundle savedInstanceState) { ... final Button btn = (Button)findViewById(R.id.button); final EditText editText = (EditText)findViewById(R.id.editText); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { DatabaseReference newElementReference = database.getReference().child(WORDS_CHILD).push(); newElementReference.setValue(editText.getText().toString()); editText.setText(""); } }); } } https://github.com/ykro/firebase-minimun-example/blob/master/app/src/main/java/com/bitandik/labs/simplefirebase/MainActivity.java MainActivity.java
  14. public class MainActivity extends AppCompatActivity { private FirebaseDatabase database; private

    String WORDS_CHILD = "words"; @Override protected void onCreate(Bundle savedInstanceState) { ... final Button btn = (Button)findViewById(R.id.button); final EditText editText = (EditText)findViewById(R.id.editText); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { DatabaseReference newElementReference = database.getReference().child(WORDS_CHILD).push(); newElementReference.setValue(editText.getText().toString()); editText.setText(""); } }); } } https://github.com/ykro/firebase-minimun-example/blob/master/app/src/main/java/com/bitandik/labs/simplefirebase/MainActivity.java MainActivity.java
  15. Work with a reference and add child or value event

    listeners to it Reading from the database
  16. https://github.com/ykro/firebase-minimun-example/blob/master/app/src/main/java/com/bitandik/labs/simplefirebase/MainActivity.java private static final String TAG = MainActivity.class.getSimpleName(); public void

    showMessage(String msg) { Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show(); Log.d(TAG, "Value is: " + msg); } MainActivity.java
  17. https://github.com/ykro/firebase-minimun-example/blob/master/app/src/main/java/com/bitandik/labs/simplefirebase/MainActivity.java @Override protected void onCreate(Bundle savedInstanceState) { ... messageReference.addValueEventListener(new ValueEventListener()

    { @Override public void onDataChange(DataSnapshot snapshot) { if (snapshot.getValue() != null) { String value = snapshot.getValue(String.class); showMessage(value); } } @Override public void onCancelled(DatabaseError error) { Log.w(TAG, "Failed to read value.", error.toException()); } }); } MainActivity.java
  18. https://github.com/ykro/firebase-minimun-example/blob/master/app/src/main/java/com/bitandik/labs/simplefirebase/MainActivity.java @Override protected void onCreate(Bundle savedInstanceState) { ... messageReference.addValueEventListener(new ValueEventListener()

    { @Override public void onDataChange(DataSnapshot snapshot) { if (snapshot.getValue() != null) { String value = snapshot.getValue(String.class); showMessage(value); } } @Override public void onCancelled(DatabaseError error) { Log.w(TAG, "Failed to read value.", error.toException()); } }); } MainActivity.java
  19. https://github.com/ykro/firebase-minimun-example/blob/master/app/src/main/java/com/bitandik/labs/simplefirebase/MainActivity.java @Override protected void onCreate(Bundle savedInstanceState) { ... messageReference.addValueEventListener(new ValueEventListener()

    { @Override public void onDataChange(DataSnapshot snapshot) { if (snapshot.getValue() != null) { String value = snapshot.getValue(String.class); showMessage(value); } } @Override public void onCancelled(DatabaseError error) { Log.w(TAG, "Failed to read value.", error.toException()); } }); } MainActivity.java
  20. https://github.com/ykro/firebase-minimun-example/blob/master/app/src/main/java/com/bitandik/labs/simplefirebase/MainActivity.java @Override protected void onCreate(Bundle savedInstanceState) { ... messageReference.addValueEventListener(new ValueEventListener()

    { @Override public void onDataChange(DataSnapshot snapshot) { if (snapshot.getValue() != null) { String value = snapshot.getValue(String.class); showMessage(value); } } @Override public void onCancelled(DatabaseError error) { Log.w(TAG, "Failed to read value.", error.toException()); } }); } MainActivity.java
  21. https://github.com/ykro/firebase-minimun-example/blob/master/app/src/main/java/com/bitandik/labs/simplefirebase/MainActivity.java @Override protected void onCreate(Bundle savedInstanceState) { ... DatabaseReference wordsReference

    = database.getReference().child(WORDS_CHILD); wordsReference.addChildEventListener(new ChildEventListener() { @Override public void onChildAdded(DataSnapshot dataSnapshot, String s) { showMessage(dataSnapshot.getValue().toString()); } ... }); } MainActivity.java
  22. https://github.com/ykro/firebase-minimun-example/blob/master/app/src/main/java/com/bitandik/labs/simplefirebase/MainActivity.java @Override protected void onCreate(Bundle savedInstanceState) { ... DatabaseReference wordsReference

    = database.getReference().child(WORDS_CHILD); wordsReference.addChildEventListener(new ChildEventListener() { @Override public void onChildAdded(DataSnapshot dataSnapshot, String s) { showMessage(dataSnapshot.getValue().toString()); } ... }); } MainActivity.java
  23. https://github.com/ykro/firebase-minimun-example/blob/master/app/src/main/java/com/bitandik/labs/simplefirebase/MainActivity.java @Override protected void onCreate(Bundle savedInstanceState) { ... DatabaseReference wordsReference

    = database.getReference().child(WORDS_CHILD); wordsReference.addChildEventListener(new ChildEventListener() { @Override public void onChildAdded(DataSnapshot dataSnapshot, String s) { showMessage(dataSnapshot.getValue().toString()); } ... }); } MainActivity.java
  24. https://github.com/ykro/firebase-minimun-example/blob/master/app/src/main/java/com/bitandik/labs/simplefirebase/MainActivity.java @Override protected void onCreate(Bundle savedInstanceState) { ... wordsReference.addChildEventListener(new ChildEventListener()

    { ... @Override public void onChildChanged(DataSnapshot dataSnapshot, String s) {} @Override public void onChildRemoved(DataSnapshot dataSnapshot) {} @Override public void onChildMoved(DataSnapshot dataSnapshot, String s) {} @Override public void onCancelled(DatabaseError databaseError) { Log.w(TAG, "Failed to read value.", databaseError.toException()); } }); } MainActivity.java
  25. https://github.com/ykro/firebase-minimun-example/blob/master/app/src/main/java/com/bitandik/labs/simplefirebase/MainActivity.java @Override protected void onCreate(Bundle savedInstanceState) { ... wordsReference.addChildEventListener(new ChildEventListener()

    { ... @Override public void onChildChanged(DataSnapshot dataSnapshot, String s) {} @Override public void onChildRemoved(DataSnapshot dataSnapshot) {} @Override public void onChildMoved(DataSnapshot dataSnapshot, String s) {} @Override public void onCancelled(DatabaseError databaseError) { Log.w(TAG, "Failed to read value.", databaseError.toException()); } }); } MainActivity.java
  26. https://github.com/ykro/firebase-minimun-example/blob/master/app/src/main/java/com/bitandik/labs/simplefirebase/MainActivity.java @Override protected void onCreate(Bundle savedInstanceState) { ... wordsReference.addChildEventListener(new ChildEventListener()

    { ... @Override public void onChildChanged(DataSnapshot dataSnapshot, String s) {} @Override public void onChildRemoved(DataSnapshot dataSnapshot) {} @Override public void onChildMoved(DataSnapshot dataSnapshot, String s) {} @Override public void onCancelled(DatabaseError databaseError) { Log.w(TAG, "Failed to read value.", databaseError.toException()); } }); } MainActivity.java
  27. https://github.com/ykro/firebase-minimun-example/blob/master/app/src/main/java/com/bitandik/labs/simplefirebase/MainActivity.java @Override protected void onCreate(Bundle savedInstanceState) { ... wordsReference.addChildEventListener(new ChildEventListener()

    { ... @Override public void onChildChanged(DataSnapshot dataSnapshot, String s) {} @Override public void onChildRemoved(DataSnapshot dataSnapshot) {} @Override public void onChildMoved(DataSnapshot dataSnapshot, String s) {} @Override public void onCancelled(DatabaseError databaseError) { Log.w(TAG, "Failed to read value.", databaseError.toException()); } }); } MainActivity.java
  28. https://github.com/ykro/firebase-minimun-example/blob/master/app/src/main/java/com/bitandik/labs/simplefirebase/MainActivity.java @Override protected void onCreate(Bundle savedInstanceState) { ... wordsReference.addChildEventListener(new ChildEventListener()

    { ... @Override public void onChildChanged(DataSnapshot dataSnapshot, String s) {} @Override public void onChildRemoved(DataSnapshot dataSnapshot) {} @Override public void onChildMoved(DataSnapshot dataSnapshot, String s) {} @Override public void onCancelled(DatabaseError databaseError) { Log.w(TAG, "Failed to read value.", databaseError.toException()); } }); } MainActivity.java
  29. dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile

    'com.android.support:appcompat-v7:24.1.1' compile 'com.android.support:design:24.1.1' compile 'com.android.support:recyclerview-v7:24.1.1' apt 'com.jakewharton:butterknife-compiler:8.2.1' compile 'com.jakewharton:butterknife:8.2.1' compile 'com.google.firebase:firebase-database:9.0.2' compile 'com.firebaseui:firebase-ui-database:0.4.3' } https://github.com/ykro/firebase-todolist-noauth/blob/master/app/build.gradle app/build.gradle
  30. dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile

    'com.android.support:appcompat-v7:24.1.1' compile 'com.android.support:design:24.1.1' compile 'com.android.support:recyclerview-v7:24.1.1' apt 'com.jakewharton:butterknife-compiler:8.2.1' compile 'com.jakewharton:butterknife:8.2.1' compile 'com.google.firebase:firebase-database:9.0.2' compile 'com.firebaseui:firebase-ui-database:0.4.3' } https://github.com/ykro/firebase-todolist-noauth/blob/master/app/build.gradle app/build.gradle
  31. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_vertical_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".activities.MainActivity">

    <android.support.v7.widget.RecyclerView android:id="@+id/recycler_view_items" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="2" android:scrollbars="vertical" android:layout_above="@+id/txtInputWrapper" /> ... </RelativeLayout> https://github.com/ykro/firebase-todolist-noauth/blob/master/app/src/main/res/layout/activity_main.xml layout/activity_main.xml
  32. <RelativeLayout > <android.support.design.widget.TextInputLayout android:id="@+id/txtInputWrapper" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_toLeftOf="@+id/fab" android:layout_toStartOf="@+id/fab"> <EditText

    android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/main.message.addelement" android:id="@+id/editTextItem" /> </android.support.design.widget.TextInputLayout> <android.support.design.widget.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_add_white_36dp" android:layout_alignBottom="@+id/txtInputWrapper" android:layout_alignParentRight="true" android:layout_alignParentEnd="true" /> </RelativeLayout> https://github.com/ykro/firebase-todolist-noauth/blob/master/app/src/main/res/layout/activity_main.xml layout/activity_main.xml
  33. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_margin="4dp" android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="wrap_content"

    android:layout_margin="@dimen/activity_horizontal_margin" android:layout_weight="1"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge" android:text="Large Text" android:id="@+id/txtItem" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="Medium Text" android:id="@+id/txtUser" /> </LinearLayout> https://github.com/ykro/firebase-todolist-noauth/blob/master/app/src/main/res/layout/row.xml layout/row.xml
  34. https://github.com/ykro/firebase-todolist-noauth/blob/master/app/src/main/java/com/bitandik/labs/todolist/models/ToDoItem.java public class ToDoItem { private String item; private String

    username; private boolean completed; public ToDoItem(){ } public ToDoItem(String item, String username) { this.username = username; this.item = item; this.completed = false; } ... //getters & setters } models/ToDoItem.java
  35. https://github.com/ykro/firebase-todolist-noauth/blob/master/app/src/main/java/com/bitandik/labs/todolist/ToDoApplication.java public class ToDoApplication extends Application { private String ITEMS_CHILD_NAME

    = "items"; private DatabaseReference itemsReference; @Override public void onCreate() { super.onCreate(); FirebaseDatabase database = FirebaseDatabase.getInstance(); database.setPersistenceEnabled(true); itemsReference = database.getReference(ITEMS_CHILD_NAME); } public DatabaseReference getItemsReference() { return itemsReference; } } ToDoApplication.java
  36. https://github.com/ykro/firebase-todolist-noauth/blob/master/app/src/main/java/com/bitandik/labs/todolist/ToDoApplication.java ToDoApplication.java public class ToDoApplication extends Application { private String

    ITEMS_CHILD_NAME = "items"; private DatabaseReference itemsReference; @Override public void onCreate() { super.onCreate(); FirebaseDatabase database = FirebaseDatabase.getInstance(); database.setPersistenceEnabled(true); itemsReference = database.getReference(ITEMS_CHILD_NAME); } public DatabaseReference getItemsReference() { return itemsReference; } }
  37. https://github.com/ykro/firebase-todolist-noauth/blob/master/app/src/main/java/com/bitandik/labs/todolist/ToDoApplication.java public class ToDoApplication extends Application { private String ITEMS_CHILD_NAME

    = "items"; private DatabaseReference itemsReference; @Override public void onCreate() { super.onCreate(); FirebaseDatabase database = FirebaseDatabase.getInstance(); database.setPersistenceEnabled(true); itemsReference = database.getReference(ITEMS_CHILD_NAME); } public DatabaseReference getItemsReference() { return itemsReference; } } ToDoApplication.java
  38. https://github.com/ykro/firebase-todolist-noauth/blob/master/app/src/main/java/com/bitandik/labs/todolist/ToDoApplication.java public class ToDoApplication extends Application { private String ITEMS_CHILD_NAME

    = "items"; private DatabaseReference itemsReference; @Override public void onCreate() { super.onCreate(); FirebaseDatabase database = FirebaseDatabase.getInstance(); database.setPersistenceEnabled(true); itemsReference = database.getReference(ITEMS_CHILD_NAME); } public DatabaseReference getItemsReference() { return itemsReference; } } ToDoApplication.java
  39. We need a ViewHolder and override methods to populate and

    create*. • populateViewHolder • onCreateViewHolder RecyclerAdapter
  40. https://github.com/ykro/firebase-todolist-noauth/blob/master/app/src/main/java/com/bitandik/labs/todolist/adapters/ToDoItemsRecyclerAdapter.java class ToDoItemViewHolder extends RecyclerView.ViewHolder { @BindView(R.id.txtItem) TextView txtItem; @BindView(R.id.txtUser)

    TextView txtUser; @BindView(R.id.imgDone) ImageView imgDone; public ToDoItemViewHolder(View itemView) { super(itemView); ButterKnife.bind(this, itemView); } } adapters/ToDoItemsRecyclerAdapter.jav a
  41. https://github.com/ykro/firebase-todolist-noauth/blob/master/app/src/main/java/com/bitandik/labs/todolist/adapters/ToDoItemsRecyclerAdapter.java @Override public void onClick(View view) { int position =

    getAdapterPosition(); ToDoItem currentItem = (ToDoItem)getItem(position); DatabaseReference reference = getRef(position); boolean completed = !currentItem.isCompleted(); currentItem.setCompleted(completed); Map<String, Object> updates = new HashMap<String, Object>(); updates.put("completed", completed); reference.updateChildren(updates); } adapters/ToDoItemsRecyclerAdapter.jav a
  42. https://github.com/ykro/firebase-todolist-noauth/blob/master/app/src/main/java/com/bitandik/labs/todolist/adapters/ToDoItemsRecyclerAdapter.java @Override public void onClick(View view) { int position =

    getAdapterPosition(); ToDoItem currentItem = (ToDoItem)getItem(position); DatabaseReference reference = getRef(position); boolean completed = !currentItem.isCompleted(); currentItem.setCompleted(completed); Map<String, Object> updates = new HashMap<String, Object>(); updates.put("completed", completed); reference.updateChildren(updates); } adapters/ToDoItemsRecyclerAdapter.jav a
  43. https://github.com/ykro/firebase-todolist-noauth/blob/master/app/src/main/java/com/bitandik/labs/todolist/adapters/ToDoItemsRecyclerAdapter.java @Override public void onClick(View view) { int position =

    getAdapterPosition(); ToDoItem currentItem = (ToDoItem)getItem(position); DatabaseReference reference = getRef(position); boolean completed = !currentItem.isCompleted(); currentItem.setCompleted(completed); Map<String, Object> updates = new HashMap<String, Object>(); updates.put("completed", completed); reference.updateChildren(updates); } adapters/ToDoItemsRecyclerAdapter.jav a
  44. https://github.com/ykro/firebase-todolist-noauth/blob/master/app/src/main/java/com/bitandik/labs/todolist/adapters/ToDoItemsRecyclerAdapter.java @Override public void onClick(View view) { int position =

    getAdapterPosition(); ToDoItem currentItem = (ToDoItem)getItem(position); DatabaseReference reference = getRef(position); boolean completed = !currentItem.isCompleted(); currentItem.setCompleted(completed); Map<String, Object> updates = new HashMap<String, Object>(); updates.put("completed", completed); reference.updateChildren(updates); } adapters/ToDoItemsRecyclerAdapter.jav a
  45. https://github.com/ykro/firebase-todolist-noauth/blob/master/app/src/main/java/com/bitandik/labs/todolist/adapters/ToDoItemsRecyclerAdapter.java @Override public void onClick(View view) { int position =

    getAdapterPosition(); ToDoItem currentItem = (ToDoItem)getItem(position); DatabaseReference reference = getRef(position); boolean completed = !currentItem.isCompleted(); currentItem.setCompleted(completed); Map<String, Object> updates = new HashMap<String, Object>(); updates.put("completed", completed); reference.updateChildren(updates); } adapters/ToDoItemsRecyclerAdapter.jav a
  46. https://github.com/ykro/firebase-todolist-noauth/blob/master/app/src/main/java/com/bitandik/labs/todolist/adapters/ToDoItemsRecyclerAdapter.java public class ToDoItemsRecyclerAdapter extends FirebaseRecyclerAdapter<ToDoItem, ToDoItemsRecyclerAdapter.ToDoItemViewHolder> { public ToDoItemsRecyclerAdapter(int

    modelLayout, DatabaseReference ref) { super(ToDoItem.class, modelLayout, ToDoItemsRecyclerAdapter.ToDoItemViewHolder.class, ref); } @Override public ToDoItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { ViewGroup view = (ViewGroup) LayoutInflater.from(parent.getContext()) .inflate(mModelLayout, parent, false); return new ToDoItemViewHolder(view); } ... } adapters/ToDoItemsRecyclerAdapter.jav a
  47. https://github.com/ykro/firebase-todolist-noauth/blob/master/app/src/main/java/com/bitandik/labs/todolist/adapters/ToDoItemsRecyclerAdapter.java adapters/ToDoItemsRecyclerAdapter.jav a public class ToDoItemsRecyclerAdapter extends FirebaseRecyclerAdapter<ToDoItem, ToDoItemsRecyclerAdapter.ToDoItemViewHolder> {

    public ToDoItemsRecyclerAdapter(int modelLayout, DatabaseReference ref) { super(ToDoItem.class, modelLayout, ToDoItemsRecyclerAdapter.ToDoItemViewHolder.class, ref); } @Override public ToDoItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { ViewGroup view = (ViewGroup) LayoutInflater.from(parent.getContext()) .inflate(mModelLayout, parent, false); return new ToDoItemViewHolder(view); } ... }
  48. https://github.com/ykro/firebase-todolist-noauth/blob/master/app/src/main/java/com/bitandik/labs/todolist/adapters/ToDoItemsRecyclerAdapter.java public class ToDoItemsRecyclerAdapter extends FirebaseRecyclerAdapter<ToDoItem, ToDoItemsRecyclerAdapter.ToDoItemViewHolder> { public ToDoItemsRecyclerAdapter(int

    modelLayout, DatabaseReference ref) { super(ToDoItem.class, modelLayout, ToDoItemsRecyclerAdapter.ToDoItemViewHolder.class, ref); } @Override public ToDoItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { ViewGroup view = (ViewGroup) LayoutInflater.from(parent.getContext()) .inflate(mModelLayout, parent, false); return new ToDoItemViewHolder(view); } ... } adapters/ToDoItemsRecyclerAdapter.jav a
  49. https://github.com/ykro/firebase-todolist-noauth/blob/master/app/src/main/java/com/bitandik/labs/todolist/adapters/ToDoItemsRecyclerAdapter.java @Override protected void populateViewHolder(ToDoItemViewHolder holder, ToDoItem item, int position)

    { String itemDescription = item.getItem(); String username = item.getUsername(); holder.txtItem.setText(itemDescription); holder.txtUser.setText(username); if (item.isCompleted()) { holder.imgDone.setVisibility(View.VISIBLE); } else { holder.imgDone.setVisibility(View.INVISIBLE); } } adapters/ToDoItemsRecyclerAdapter.jav a
  50. https://github.com/ykro/firebase-todolist-noauth/blob/master/app/src/main/java/com/bitandik/labs/todolist/adapters/ToDoItemsRecyclerAdapter.java @Override protected void populateViewHolder(ToDoItemViewHolder holder, ToDoItem item, int position)

    { String itemDescription = item.getItem(); String username = item.getUsername(); holder.txtItem.setText(itemDescription); holder.txtUser.setText(username); if (item.isCompleted()) { holder.imgDone.setVisibility(View.VISIBLE); } else { holder.imgDone.setVisibility(View.INVISIBLE); } } adapters/ToDoItemsRecyclerAdapter.jav a
  51. https://github.com/ykro/firebase-todolist-noauth/blob/master/app/src/main/java/com/bitandik/labs/todolist/adapters/ToDoItemsRecyclerAdapter.java @Override protected void populateViewHolder(ToDoItemViewHolder holder, ToDoItem item, int position)

    { String itemDescription = item.getItem(); String username = item.getUsername(); holder.txtItem.setText(itemDescription); holder.txtUser.setText(username); if (item.isCompleted()) { holder.imgDone.setVisibility(View.VISIBLE); } else { holder.imgDone.setVisibility(View.INVISIBLE); } } adapters/ToDoItemsRecyclerAdapter.jav a
  52. public class MainActivity extends AppCompatActivity { @BindView(R.id.recycler_view_items) RecyclerView recyclerView; @BindView(R.id.editTextItem)

    EditText editTextItem; private DatabaseReference databaseReference; private FirebaseRecyclerAdapter adapter; ... } https://github.com/ykro/firebase-todolist-noauth/blob/master/app/src/main/java/com/bitandik/labs/todolist/activities/MainActivity.java activities/MainActivity.java
  53. @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); setupUsername();

    SharedPreferences prefs = getApplication().getSharedPreferences("ToDoPrefs", 0); String username = prefs.getString("username", null); setTitle(username); ToDoApplication app = (ToDoApplication)getApplicationContext(); databaseReference = app.getItemsReference(); adapter = new ToDoItemsRecyclerAdapter(R.layout.row, databaseReference); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setAdapter(adapter); } https://github.com/ykro/firebase-todolist-noauth/blob/master/app/src/main/java/com/bitandik/labs/todolist/activities/MainActivity.java activities/MainActivity.java
  54. @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); setupUsername();

    SharedPreferences prefs = getApplication().getSharedPreferences("ToDoPrefs", 0); String username = prefs.getString("username", null); setTitle(username); ToDoApplication app = (ToDoApplication)getApplicationContext(); databaseReference = app.getItemsReference(); adapter = new ToDoItemsRecyclerAdapter(R.layout.row, databaseReference); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setAdapter(adapter); } https://github.com/ykro/firebase-todolist-noauth/blob/master/app/src/main/java/com/bitandik/labs/todolist/activities/MainActivity.java activities/MainActivity.java
  55. @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); setupUsername();

    SharedPreferences prefs = getApplication().getSharedPreferences("ToDoPrefs", 0); String username = prefs.getString("username", null); setTitle(username); ToDoApplication app = (ToDoApplication)getApplicationContext(); databaseReference = app.getItemsReference(); adapter = new ToDoItemsRecyclerAdapter(R.layout.row, databaseReference); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setAdapter(adapter); } https://github.com/ykro/firebase-todolist-noauth/blob/master/app/src/main/java/com/bitandik/labs/todolist/activities/MainActivity.java activities/MainActivity.java
  56. private void setupUsername() { SharedPreferences prefs = getApplication().getSharedPreferences("ToDoPrefs", 0); String

    username = prefs.getString("username", null); if (username == null) { Random r = new Random(); username = "AndroidUser" + r.nextInt(100000); prefs.edit().putString("username", username).commit(); } } https://github.com/ykro/firebase-todolist-noauth/blob/master/app/src/main/java/com/bitandik/labs/todolist/activities/MainActivity.java activities/MainActivity.java
  57. @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); setupUsername();

    SharedPreferences prefs = getApplication().getSharedPreferences("ToDoPrefs", 0); String username = prefs.getString("username", null); setTitle(username); ToDoApplication app = (ToDoApplication)getApplicationContext(); databaseReference = app.getItemsReference(); adapter = new ToDoItemsRecyclerAdapter(R.layout.row, databaseReference); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setAdapter(adapter); } https://github.com/ykro/firebase-todolist-noauth/blob/master/app/src/main/java/com/bitandik/labs/todolist/activities/MainActivity.java activities/MainActivity.java
  58. @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); setupUsername();

    SharedPreferences prefs = getApplication().getSharedPreferences("ToDoPrefs", 0); String username = prefs.getString("username", null); setTitle(username); ToDoApplication app = (ToDoApplication)getApplicationContext(); databaseReference = app.getItemsReference(); adapter = new ToDoItemsRecyclerAdapter(R.layout.row, databaseReference); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setAdapter(adapter); } https://github.com/ykro/firebase-todolist-noauth/blob/master/app/src/main/java/com/bitandik/labs/todolist/activities/MainActivity.java activities/MainActivity.java
  59. @OnClick(R.id.fab) public void addToDoItem() { SharedPreferences prefs = getApplication().getSharedPreferences("ToDoPrefs", 0);

    String username = prefs.getString("username", null); String itemText = editTextItem.getText().toString(); editTextItem.setText(""); InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE); inputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0); if (!itemText.isEmpty()) { ToDoItem toDoItem = new ToDoItem(itemText.trim(), username); databaseReference.push().setValue(toDoItem); } } https://github.com/ykro/firebase-todolist-noauth/blob/master/app/src/main/java/com/bitandik/labs/todolist/activities/MainActivity.java activities/MainActivity.java
  60. @OnClick(R.id.fab) public void addToDoItem() { SharedPreferences prefs = getApplication().getSharedPreferences("ToDoPrefs", 0);

    String username = prefs.getString("username", null); String itemText = editTextItem.getText().toString(); editTextItem.setText(""); InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE); inputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0); if (!itemText.isEmpty()) { ToDoItem toDoItem = new ToDoItem(itemText.trim(), username); databaseReference.push().setValue(toDoItem); } } https://github.com/ykro/firebase-todolist-noauth/blob/master/app/src/main/java/com/bitandik/labs/todolist/activities/MainActivity.java activities/MainActivity.java
  61. @OnClick(R.id.fab) public void addToDoItem() { SharedPreferences prefs = getApplication().getSharedPreferences("ToDoPrefs", 0);

    String username = prefs.getString("username", null); String itemText = editTextItem.getText().toString(); editTextItem.setText(""); InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE); inputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0); if (!itemText.isEmpty()) { ToDoItem toDoItem = new ToDoItem(itemText.trim(), username); databaseReference.push().setValue(toDoItem); } } https://github.com/ykro/firebase-todolist-noauth/blob/master/app/src/main/java/com/bitandik/labs/todolist/activities/MainActivity.java activities/MainActivity.java
  62. @OnClick(R.id.fab) public void addToDoItem() { SharedPreferences prefs = getApplication().getSharedPreferences("ToDoPrefs", 0);

    String username = prefs.getString("username", null); String itemText = editTextItem.getText().toString(); editTextItem.setText(""); InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE); inputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0); if (!itemText.isEmpty()) { ToDoItem toDoItem = new ToDoItem(itemText.trim(), username); databaseReference.push().setValue(toDoItem); } } https://github.com/ykro/firebase-todolist-noauth/blob/master/app/src/main/java/com/bitandik/labs/todolist/activities/MainActivity.java activities/MainActivity.java
  63. dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile

    'com.android.support:appcompat-v7:24.1.1' compile 'com.android.support:design:24.1.1' compile 'com.android.support:recyclerview-v7:24.1.1' apt 'com.jakewharton:butterknife-compiler:8.2.1' compile 'com.jakewharton:butterknife:8.2.1' compile 'com.google.firebase:firebase-database:9.0.2' compile 'com.firebaseui:firebase-ui-database:0.4.3' } https://github.com/ykro/firebase-todolist-noauth/blob/master/app/build.gradle app/build.gradle
  64. dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile

    'com.android.support:appcompat-v7:24.1.1' compile 'com.android.support:design:24.1.1' compile 'com.android.support:recyclerview-v7:24.1.1' apt 'com.jakewharton:butterknife-compiler:8.2.1' compile 'com.jakewharton:butterknife:8.2.1' compile 'com.google.firebase:firebase-database:9.0.2' compile 'com.firebaseui:firebase-ui:0.4.3' } https://github.com/ykro/firebase-todolist/blob/master/app/build.gradle app/build.gradle
  65. buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' resValue

    "string", "facebook_application_id", project.property('facebook_application_id') } debug { resValue "string", "facebook_application_id", project.property('facebook_application_id') } } https://github.com/ykro/firebase-todolist/blob/master/app/build.gradle app/build.gradle
  66. https://github.com/ykro/firebase-todolist/blob/master/app/src/main/java/com/bitandik/labs/todolist/ToDoApplication.java public class ToDoApplication extends Application { private String ITEMS_CHILD_NAME

    = "items"; private DatabaseReference itemsReference; private FirebaseAuth auth; @Override public void onCreate() { super.onCreate(); FirebaseDatabase database = FirebaseDatabase.getInstance(); database.setPersistenceEnabled(true); itemsReference = database.getReference(ITEMS_CHILD_NAME); auth = FirebaseAuth.getInstance(); } //getters } ToDoApplication.java
  67. https://github.com/ykro/firebase-todolist/blob/master/app/src/main/java/com/bitandik/labs/todolist/ToDoApplication.java public class ToDoApplication extends Application { private String ITEMS_CHILD_NAME

    = "items"; private DatabaseReference itemsReference; private FirebaseAuth auth; @Override public void onCreate() { super.onCreate(); FirebaseDatabase database = FirebaseDatabase.getInstance(); database.setPersistenceEnabled(true); itemsReference = database.getReference(ITEMS_CHILD_NAME); auth = FirebaseAuth.getInstance(); } //getters } ToDoApplication.java
  68. https://github.com/ykro/firebase-todolist/blob/master/app/src/main/java/com/bitandik/labs/todolist/ToDoApplication.java public class ToDoApplication extends Application { private String ITEMS_CHILD_NAME

    = "items"; private DatabaseReference itemsReference; private FirebaseAuth auth; @Override public void onCreate() { super.onCreate(); FirebaseDatabase database = FirebaseDatabase.getInstance(); database.setPersistenceEnabled(true); itemsReference = database.getReference(ITEMS_CHILD_NAME); auth = FirebaseAuth.getInstance(); } //getters } ToDoApplication.java
  69. public class LoginActivity extends AppCompatActivity { private FirebaseAuth auth; @Override

    protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); ToDoApplication app = (ToDoApplication)getApplicationContext(); auth = app.getAuth(); doLogin(); } ... } https://github.com/ykro/firebase-todolist/blob/master/app/src/main/java/com/bitandik/labs/todolist/activities/LoginActivity.java activities/LoginActivity.java
  70. public class LoginActivity extends AppCompatActivity { private FirebaseAuth auth; @Override

    protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); ToDoApplication app = (ToDoApplication)getApplicationContext(); auth = app.getAuth(); doLogin(); } ... } https://github.com/ykro/firebase-todolist/blob/master/app/src/main/java/com/bitandik/labs/todolist/activities/LoginActivity.java activities/LoginActivity.java
  71. public class LoginActivity extends AppCompatActivity { private FirebaseAuth auth; @Override

    protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); ToDoApplication app = (ToDoApplication)getApplicationContext(); auth = app.getAuth(); doLogin(); } ... } https://github.com/ykro/firebase-todolist/blob/master/app/src/main/java/com/bitandik/labs/todolist/activities/LoginActivity.java activities/LoginActivity.java
  72. private void doLogin() { FirebaseUser currentUser = auth.getCurrentUser(); if (currentUser

    != null) { String username = currentUser.getDisplayName(); SharedPreferences prefs = getApplication().getSharedPreferences("ToDoPrefs", 0); prefs.edit().putString("username", username).commit(); Intent i = new Intent(this, MainActivity.class); i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); startActivity(i); } else { ... } } https://github.com/ykro/firebase-todolist/blob/master/app/src/main/java/com/bitandik/labs/todolist/activities/LoginActivity.java activities/LoginActivity.java
  73. private void doLogin() { FirebaseUser currentUser = auth.getCurrentUser(); if (currentUser

    != null) { String username = currentUser.getDisplayName(); SharedPreferences prefs = getApplication().getSharedPreferences("ToDoPrefs", 0); prefs.edit().putString("username", username).commit(); Intent i = new Intent(this, MainActivity.class); i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); startActivity(i); } else { ... } } https://github.com/ykro/firebase-todolist/blob/master/app/src/main/java/com/bitandik/labs/todolist/activities/LoginActivity.java activities/LoginActivity.java
  74. private void doLogin() { FirebaseUser currentUser = auth.getCurrentUser(); if (currentUser

    != null) { String username = currentUser.getDisplayName(); SharedPreferences prefs = getApplication().getSharedPreferences("ToDoPrefs", 0); prefs.edit().putString("username", username).commit(); Intent i = new Intent(this, MainActivity.class); i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); startActivity(i); } else { ... } } https://github.com/ykro/firebase-todolist/blob/master/app/src/main/java/com/bitandik/labs/todolist/activities/LoginActivity.java activities/LoginActivity.java
  75. private void doLogin() { FirebaseUser currentUser = auth.getCurrentUser(); if (currentUser

    != null) { ... } else { startActivityForResult( AuthUI.getInstance() .createSignInIntentBuilder() .setProviders( AuthUI.EMAIL_PROVIDER, AuthUI.GOOGLE_PROVIDER, AuthUI.FACEBOOK_PROVIDER) .build(), RC_SIGN_IN); } } https://github.com/ykro/firebase-todolist/blob/master/app/src/main/java/com/bitandik/labs/todolist/activities/LoginActivity.java activities/LoginActivity.java
  76. private void doLogin() { FirebaseUser currentUser = auth.getCurrentUser(); if (currentUser

    != null) { ... } else { startActivityForResult( AuthUI.getInstance() .createSignInIntentBuilder() .setProviders( AuthUI.EMAIL_PROVIDER, AuthUI.GOOGLE_PROVIDER, AuthUI.FACEBOOK_PROVIDER) .build(), RC_SIGN_IN); } } https://github.com/ykro/firebase-todolist/blob/master/app/src/main/java/com/bitandik/labs/todolist/activities/LoginActivity.java activities/LoginActivity.java
  77. @Override public void onActivityResult(int requestCode, int resultCode, Intent data) {

    super.onActivityResult(requestCode, resultCode, data); if (requestCode == RC_SIGN_IN) { if (resultCode == RESULT_OK) { doLogin(); finish(); } } } https://github.com/ykro/firebase-todolist/blob/master/app/src/main/java/com/bitandik/labs/todolist/activities/LoginActivity.java activities/LoginActivity.java
  78. Database • Attach/Detach child event listener and modify adapter dataset.

    Auth • Design layout • Handle authentication flow Without Firebase-UI
  79. Store uid under each item, check if it’s a new

    node or if owner is modifying Security rules