How to Read Data From Firebase Database

Firebase for Android: Database tutorial Android 17.03.2017

android_firebase.png Introduction

With Firebase, y'all tin store and sync information to a NoSQL cloud database. The data is stored every bit JSON, synced to all connected clients in realtime, and available when your app goes offline. It offers APIs that enable y'all to authenticate users with email and password, Facebook, Twitter, GitHub, Google, bearding auth, or to integrate with existing hallmark arrangement. Other than the Realtime Database and Authentication, information technology offers a myriad of other services including Cloud Messaging, Storage, Hosting, Remote Config, Examination Lab, Crash Reporting, Notification, App Indexing, Dynamic Links, Invites, AdWords, AdMob.

In this tutorial, you'll create a uncomplicated ToDo app that will show how to save and retrieve data from Firebase, how to authenticate users, set read/write permissions on the information and validate the information on the server.

Suppose we take to store an Item to our reference then nosotros will create a model class every bit below.

public course Item {     individual String championship;     public Item() {}     public Item(String title) {         this.championship = title;     }     public String getTitle() {         return title;     }     public void setTitle(String title) {         this.title = championship;     } }        

Firebase stores data in JSON format. In our database, each user will take an array of to-do items named items. Each particular will have a title.

Let'due south look at basic operations. First we need to get the Firebase Database Reference. You can use DatabaseReference to become the reference.

private DatabaseReference db; db = FirebaseDatabase.getInstance().getReference("path");        

The information is stored in the JSON Tree grade so yous need to get the reference of an specified path.

Nosotros can practice write operations by setValue() method. It will take a model java class object that will hold all the variables to be stored in the reference. The same method will exist used to update the values at it overwrites the data of the specified reference.

Now to save the Item we will use setValue() method.

Detail item = new Item(title); db.child(id).setValue(detail);        

To go a unique id use push().getKey() method

String id = db.push().getKey();        

Use following snippet for update the Detail

// getting the specified detail reference DatabaseReference db = FirebaseDatabase.getInstance().getReference().kid(id);  // updating detail Particular item = new Item(championship); db.setValue(item);        

Firebase utilizes listeners to watch for changes in a specified node (read the Detail). It is similar to an event handler in the sense that a code is triggered based on a certain circumstance. In our case, whenever changes in that node's information occur, the listener automatically provides the awarding updated information, called a snapshot. The application tin can then use information from the snapshot to update the UI.

There are several types of listeners for Firebase, and each listener type has a different kind of callback that is triggered when the listener is activated. There are two types of listeners: ValueEventListener and ChildEventListener.

A ValueEventListener listens for data changes to a specific location in your database - i.due east a node. ValueEventListener has 1 event callback method, onDataChange() to read a static snapshot of the contents at a given path, equally they existed at the fourth dimension of the consequence. This method is triggered once when the listener is fastened and again every time the information, including children, changes. The upshot callback is passed a snapshot containing all data at that location, including child information. If there is no data, the snapshot returned is zilch. If the Effect can not exist completed, a second callback method, onCancelled() is called.

A ChildEventListener listens for changes to the children of a specific database reference, for instance the root node of a database. It has the post-obit callback methods:

  • onCancelled(DatabaseError mistake). This method will exist triggered in the event that this listener either failed at the server, or is removed as a result of the security and Firebase rules.
  • onChildAdded(DataSnapshot snapshot, String previousChildName). This method will be triggered when a new child is added to the location to which this listener was added.
  • onChildChanged(DataSnapshot snapshot, Cord previousChildName). This method volition be triggered when the information at a child location has changed.
  • onChildMoved(DataSnapshot snapshot, String previousChildName). This method will be triggered when a child location'south priority changes.
  • onChildRemoved(DataSnapshot snapshot). This method will be triggered when a child is removed from the location to which this listener was added.

For read operation we volition attache a ValueEventListener to the reference.

db.addValueEventListener(new ValueEventListener() {     @Override     public void onDataChange(DataSnapshot dataSnapshot) {         Item particular = dataSnapshot.getValue(Particular.class);         System.out.println(item);     }      @Override     public void onCancelled(DatabaseError databaseError) {         Arrangement.out.println("The read failed: " + databaseError.getCode());     } });        

Whenever you will change something in the database the method onDataChange() will be executed. Information technology contains all the information within the specified path in the reference. We can use the DataSnapshot object to read all the data within the reference. If some fault occurres onCancelled() method volition be called. onDataChange() method will also called once after the app launch and hence yous can read the data at starting also.

To query the Item we can apply Query class. Listeners are fastened, and they will be triggered when the corresponding data changes. Instances of Query are obtained by calling startAt(), endAt(), or limit() on a DatabaseReference.

private void findItem(String championship) {     Query query = db.orderByChild("title").equalTo(title);     query.addChildEventListener(new ChildEventListener() {         @Override         public void onChildAdded(DataSnapshot dataSnapshot, Cord s) {             // do something         }          @Override         public void onChildChanged(DataSnapshot dataSnapshot, String southward) {}          @Override         public void onChildRemoved(DataSnapshot dataSnapshot) {}          @Override         public void onChildMoved(DataSnapshot dataSnapshot, Cord south) {}          @Override         public void onCancelled(DatabaseError databaseError) {             Log.d(TAG, "Item not establish: this item is not in the list");         }     }); }        

To delete the Item nosotros tin can employ removeValue() method. More nearly Crud operation you tin can read here.

To go started, create a new projection named ToDo. Fix Minimum SDK as API 15 in the side by side window and select Empty Action in the next. Click Finish on the last window, leaving the settings at their default.

To configure the project to employ the Firebase platform, open the Firebase Assistant window by clicking on Tools > Firebase. Now from the assistant go to Hallmark and click E-mail and password aithentication. Next, press the Connect to Firebase button and brand sure that the Create new Firebase projection option is selected. Finaly, click Add Firebase Authentication.

android_firebase_setup.png

Echo the aforementioned steps for Realtime Database.

Now yous have connected Firebase platform with Authentication and Realtime Database. As well yous can manage your Firebase data from Firebase console.

Instance of Hallmark and Realtime database

Create an empty activity by selecting the File -> New -> Action -> Empty Activity menu particular and name it LogInActivity. Create some other and proper name it SignUpActivity.

Change the contents of the activity_log_in.xml layout file to:

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:app="http://schemas.android.com/apk/res-auto"     xmlns:tools="http://schemas.android.com/tools"     android:layout_width="match_parent"     android:layout_height="match_parent"     tools:context="me.proft.todofirebase.LogInActivity">      <EditText         android:id="@+id/etEmail"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:layout_alignParentLeft="true"         android:layout_alignParentTop="true"         android:ems="ten"         android:inputType="textEmailAddress"         android:hint="@string/email_hint" >          <requestFocus />     </EditText>      <EditText         android:id="@+id/etPassword"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:layout_alignLeft="@+id/etEmail"         android:layout_below="@+id/etEmail"         android:ems="10"         android:hint="@string/password_hint"         android:inputType="textPassword" />      <Button         android:id="@+id/btnLogin"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:layout_alignLeft="@+id/etPassword"         android:layout_below="@+id/etPassword"         android:text="@string/login_button_label" />      <TextView         android:id="@+id/tvSignUp"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_below="@+id/btnLogin"         android:layout_centerHorizontal="truthful"         android:layout_marginTop="69dp"         android:text="@string/sign_up_text" />  </RelativeLayout>        

Change the contents of the activity_sign_up.xml layout file to:

<?xml version="i.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:app="http://schemas.android.com/apk/res-auto"     xmlns:tools="http://schemas.android.com/tools"     android:layout_width="match_parent"     android:layout_height="match_parent"     tools:context="me.proft.todofirebase.SignUpActivity">      <EditText         android:id="@+id/etEmail"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:layout_alignParentLeft="true"         android:layout_alignParentTop="true"         android:ems="10"         android:inputType="textEmailAddress"         android:hint="@cord/email_hint" >          <requestFocus />     </EditText>      <EditText         android:id="@+id/etPassword"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:layout_alignLeft="@+id/etEmail"         android:layout_below="@+id/etEmail"         android:ems="10"         android:inputType="textPassword"         android:hint="@string/password_hint" />      <Button         android:id="@+id/btnSignup"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:layout_alignLeft="@+id/etPassword"         android:layout_below="@+id/etPassword"         android:text="@string/sign_up_button_label" /> </RelativeLayout>        

These layouts are for the Login and SignUp views.

android_firebase_signup.png

Add the post-obit to values/strings.xml.

<string name="password_hint">Countersign</string> <string proper name="email_hint">Electronic mail</string> <string proper noun="sign_up_button_label">Sign Upward</string> <string name="signup_error_message">Delight make sure y'all enter an email address and password!</string> <cord proper noun="signup_error_title">Error!</cord> <cord proper name="signup_success">Account successfully created! Y'all tin now Login.</cord> <cord name="login_error_message">Please make certain y'all enter an email address and password!</cord> <cord name="login_error_title">Mistake!</cord> <string proper name="login_button_label">Login</string> <string proper noun="sign_up_text">Sign Upward!</cord> <string name="title_activity_login">Sign in</string> <string name="add_item">Add New Item</cord> <string name="action_logout">Logout</string>        

The app will brandish the ToDo items in a list view that volition occupy most of the screen. At the bottom of the screen, will exist an edit text field and a push to add items to the list. And then, change activity_main.xml to the below:

<?xml version="1.0" encoding="utf-viii"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:app="http://schemas.android.com/apk/res-machine"     xmlns:tools="http://schemas.android.com/tools"     android:orientation="vertical"     android:layout_width="match_parent"     android:layout_height="match_parent"     tools:context=".MainActivity">      <ListView         android:id="@+id/lvItems"         android:layout_width="match_parent"         android:layout_height="0dp"         android:layout_weight="ane">     </ListView>      <LinearLayout         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:orientation="vertical"         android:layout_gravity="bottom">         <EditText             android:id="@+id/etTitle"             android:layout_width="match_parent"             android:layout_height="wrap_content"/>         <Push             android:id="@+id/btnAdd"             android:layout_width="match_parent"             android:layout_height="wrap_content"             android:text="@string/add_item"/>     </LinearLayout> </LinearLayout>        

Before retrieving and saving data from the Firebase server, you need to set up authentication and add together rules that restrict access to information and validate user input before it'south saved.

The Firebase API has built-in methods for email/password, Facebook, Twitter, GitHub, Google and anonymous authentication. We will employ email and password hallmark.

Caput over to the Firebase console and open your project's Dashboard by clicking on the project. If y'all select Database from the left panel, you volition be able to come across projection's data that is in JSON format.

Firebase stores all database information as JSON objects. There are no tables or records. When you lot add data to the JSON tree, it becomes a fundamental in the existing JSON structure.

At the moment y'all can only come across the root node.

From the left console, click on Authentication and so select the Sign In Method tab on the right. Enable Electronic mail/Countersign authentication from the given providers.

In Android Studio, add together the post-obit method to MainActivity.

private void loadLogInView() {     Intent intent = new Intent(this, LogInActivity.class);     intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);     intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);     startActivity(intent); }        

This navigates to the Login view and clears the action stack. This prevents the user going dorsum to the main activity when they press the Back button from the Login view.

Add together the following variables to the class.

private FirebaseAuth auth; private FirebaseUser user;        

Then add the following to the bottom of onCreate().

// initialize Firebase Auth auth = FirebaseAuth.getInstance(); user = auth.getCurrentUser();  if (user == nil) {     // not logged in, launch the Log In activity     loadLogInView(); }        

Here you bank check for the logged in user. If the user isn't logged in, getCurrentUser() will return aught, otherwise it will return a FirebaseUser object which will contain details of the logged in user. If the user isn't logged in, loadLogInView() is called which redirects the user to the Login view.

Change LogInActivity.

public grade LogInActivity extends AppCompatActivity {     protected EditText etEmail;     protected EditText etPassword;     protected Button btnLogin;     protected TextView tvSignUp;     private FirebaseAuth auth;      @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_log_in);          // initialize FirebaseAuth         auth = FirebaseAuth.getInstance();          if (auth.getCurrentUser() != null) {             Intent intent = new Intent(LogInActivity.this, MainActivity.class);             startActivity(intent);         }          tvSignUp = (TextView) findViewById(R.id.tvSignUp);         etEmail = (EditText) findViewById(R.id.etEmail);         etPassword = (EditText) findViewById(R.id.etPassword);         btnLogin = (Button) findViewById(R.id.btnLogin);          tvSignUp.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View five) {                 Intent intent = new Intent(LogInActivity.this, SignUpActivity.grade);                 startActivity(intent);             }         });          btnLogin.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View v) {                 String email = etEmail.getText().toString().trim();                 String countersign = etPassword.getText().toString().trim();                  if (electronic mail.isEmpty() || password.isEmpty()) {                     AlertDialog.Builder architect = new AlertDialog.Builder(LogInActivity.this);                     architect.setMessage(R.string.login_error_message)                             .setTitle(R.string.login_error_title)                             .setPositiveButton(android.R.string.ok, null);                     AlertDialog dialog = builder.create();                     dialog.evidence();                 } else {                     auth.signInWithEmailAndPassword(e-mail, password)                             .addOnCompleteListener(LogInActivity.this, new OnCompleteListener<AuthResult>() {                                 @Override                                 public void onComplete(@NonNull Task<AuthResult> task) {                                     if (job.isSuccessful()) {                                         Intent intent = new Intent(LogInActivity.this, MainActivity.class);                                         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);                                         startActivity(intent);                                     } else {                                         AlertDialog.Architect builder = new AlertDialog.Builder(LogInActivity.this);                                         builder.setMessage(task.getException().getMessage())                                                 .setTitle(R.string.login_error_title)                                                 .setPositiveButton(android.R.string.ok, null);                                         AlertDialog dialog = builder.create();                                         dialog.show();                                     }                                 }                             });                 }             }         });     } }        

This initiates the view elements and the FirebaseAuth object, which is the entry signal of the Firebase Authentication SDK. An issue listener is added to the SignUp text view that will open the SignUp action when tapped. Another event listener on the Login button performs validation on the user input, ensuring the user entered text for both fields. It then calls the Firebase server with signInWithEmailAndPassword(). The function takes the user electronic mail and password and returns a Task of AuthResult. You bank check if the Task is successful and redirect the user to the MainActivity, otherwise bear witness them an error message.

Apart from signInWithEmailAndPassword(), y'all tin use the following to log in the user:

  • signInWithCredential(AuthCredential) method tries to sign in a user with the given AuthCredential. Use this method to sign in a user into your Firebase Authentication system. First retrieve the credential either straight from the user, in case of EmailAuthCredential, or from a supported authentication SDK, such as Google Sign-In or Facebook.
  • signInAnonymously() method signs in the user anonymously without requiring whatever credential. This method creates a new account in your Firebase Authentication organisation, except in the case where there was already an anonymous user signed in into this app.
  • signInWithCustomToken(String) metod tries to sign in a user with a given Custom Token. Apply this method after you retrieve a Firebase Auth Custom Token from your server, to sign in a user into your Firebase Authentication system.

With the Login functionality done, let'southward ready upwardly Sign Up.

Alter SignUpActivity as shown.

public class SignUpActivity extends AppCompatActivity {     protected EditText etPassword;     protected EditText etEmail;     protected Push button btnSignup;     private FirebaseAuth auth;      @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_sign_up);          // initialize FirebaseAuth         auth = FirebaseAuth.getInstance();          etPassword = (EditText)findViewById(R.id.etPassword);         etEmail = (EditText)findViewById(R.id.etEmail);         btnSignup = (Button)findViewById(R.id.btnSignup);          btnSignup.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View v) {                 String password = etPassword.getText().toString().trim();                 Cord electronic mail = etEmail.getText().toString().trim();                  if (countersign.isEmpty() || email.isEmpty()) {                     AlertDialog.Builder builder = new AlertDialog.Architect(SignUpActivity.this);                     architect.setMessage(R.string.signup_error_message)                             .setTitle(R.string.signup_error_title)                             .setPositiveButton(android.R.string.ok, null);                     AlertDialog dialog = builder.create();                     dialog.show();                 } else {                     auth.createUserWithEmailAndPassword(email, countersign)                             .addOnCompleteListener(SignUpActivity.this, new OnCompleteListener<AuthResult>() {                                 @Override                                 public void onComplete(@NonNull Chore<AuthResult> job) {                                     if (task.isSuccessful()) {                                         Intent intent = new Intent(SignUpActivity.this, MainActivity.class);                                         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);                                         startActivity(intent);                                     } else {                                         AlertDialog.Builder builder = new AlertDialog.Architect(SignUpActivity.this);                                         builder.setMessage(task.getException().getMessage())                                                 .setTitle(R.cord.login_error_title)                                                 .setPositiveButton(android.R.cord.ok, zippo);                                         AlertDialog dialog = builder.create();                                         dialog.testify();                                     }                                 }                             });                 }             }         });     } }        

The createUserWithEmailAndPassword() method tries to create a new user account with the given email address and password. If successful, information technology also signs the user into the app. A Task of AuthResult is returned with the effect of the operation. You check to run across if registration was successful and redirect the user to MainActivity, otherwise testify them an error bulletin. In your app, yous can check for the exception thrown to decide on the error message you will show to your users. The following are the possible exceptions thrown in case of an error in creating an account.

  • FirebaseAuthWeakPasswordException thrown if the password is not strong plenty
  • FirebaseAuthInvalidCredentialsException thrown if the email address is malformed
  • FirebaseAuthUserCollisionException thrown if there already exists an account with the given email

If registration is successful, you volition be directed to the MainActivity. If you look at the Firebase console, y'all should be able to meet the created user nether Auth > Users.

The Firebase team built an open source library called FirebaseUI that simplifies the procedure of calculation Hallmark and connecting common UI elements to the Firebase database. Read the documentation to learn more about the library.

Authority and Data Validation

Identifying your user is only one part of security. One time you know who they are, you need a way to control their admission to data in your Firebase database.

Firebase has a declarative language for specifying rules that live on the Firebase servers and determine the security of your app. You can edit them on the Database > Rules tab.

The Security rules allow you lot to control access to each office of your database. Past default, Firebase has security rules that require users to be authenticated.

{   "rules": {     ".read": "auth != null",     ".write": "auth != nix"   } }        

Firebase Database Rules take a JavaScript-like syntax and come up in four types:

  • .read describes if and when information is allowed to be read by users.
  • .write describes if and when data is allowed to exist written.
  • .validate defines what a correctly formatted value will look like, whether it has child attributes, and the data type.
  • .indexOn specifies a child to index to support ordering and querying.

.read and .write rules cascade, so the following ruleset grants read access to any data at path /foo/ (tin likewise refer to information technology as the node foo) equally well every bit any deeper paths such as /foo/bar/baz. Notation that .read and .write rules shallower in the database override deeper rules, so read admission to /foo/bar/baz would even so be granted in this example even if a dominion at the path /foo/bar/baz evaluated to false. .validate rules do not pour.

Alter the rules every bit shown and hit Publish.

{   "rules": {     "users": {       "$uid": {         ".read": "auth != nil && auth.uid == $uid",         ".write": "auth != zippo && auth.uid == $uid",         "items": {           "$item_id": {             "championship": {               ".validate": "newData.isString() && newData.val().length > 0"             }           }         }       }     }   } }        

In the higher up rules, auth != null && auth.uid == $uid restricts read and write permission of data on the users node (as well every bit its child nodes) to the user whose uid matches the id of the logged in user (auth.uid). The $uid is a variable that holds the value at that node and not the proper noun of the node itself. With this rule, not only will the user need to be authenticated to read or write whatsoever data to the node and its children, but they will also only accept access to their own data.

The Firebase Database Rules include built-in variables and functions that allow y'all to refer to other paths, server-side timestamps, authentication information, and more.

Validation rules are cracking but they shouldn't replace data validation lawmaking in your app. You should still validate input in you app to improve performance.

Saving and Retrieving Data

Modify MainActivity as shown.

public course MainActivity extends AppCompatActivity {     private FirebaseAuth auth;     private FirebaseUser user;     private DatabaseReference db;      @Override     protected void onCreate(Package savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);          // initialize Firebase Auth         auth = FirebaseAuth.getInstance();         user = auth.getCurrentUser();         db = FirebaseDatabase.getInstance().getReference();          if (user == null) {             // not logged in, launch the Log In activeness             loadLogInView();         } else {             final EditText etTitle = (EditText) findViewById(R.id.etTitle);             final Button btnAdd = (Push button) findViewById(R.id.btnAdd);             final Cord userId = user.getUid();             final ListView lvItems = (ListView) findViewById(R.id.lvItems);             last ArrayAdapter<Cord> adapter = new ArrayAdapter<>(this,                   android.R.layout.simple_list_item_1, android.R.id.text1);              lvItems.setAdapter(adapter);              btnAdd.setOnClickListener(new View.OnClickListener() {                 public void onClick(View five) {                     String title = etTitle.getText().toString();                     //db.child("users").kid(userId).kid("items").push().child("title").setValue(championship);                     Item item = new Item(title );                     db.child("users").child(userId).child("items").push button().setValue(item);                     etTitle.setText("");                 }             });              // delete items when clicked             lvItems.setOnItemClickListener(new AdapterView.OnItemClickListener() {                 public void onItemClick(AdapterView<?> parent, View view, int position, long id) {                     db.child("users").kid(userId).child("items")                             .orderByChild("title")                             .equalTo((String) lvItems.getItemAtPosition(position))                             .addListenerForSingleValueEvent(new ValueEventListener() {                                 @Override                                 public void onDataChange(DataSnapshot dataSnapshot) {                                     if (dataSnapshot.hasChildren()) {                                         DataSnapshot firstChild = dataSnapshot.getChildren().iterator().next();                                         firstChild.getRef().removeValue();                                     }                                 }                                  @Override                                 public void onCancelled(DatabaseError databaseError) {}                             });                 }             });              // use Firebase to populate the list             db.kid("users").child(userId).child("items").addChildEventListener(new ChildEventListener() {                 @Override                 public void onChildAdded(DataSnapshot dataSnapshot, String s) {                     adapter.add((String) dataSnapshot.child("title").getValue());                 }                  @Override                 public void onChildChanged(DataSnapshot dataSnapshot, String s) {}                  @Override                 public void onChildRemoved(DataSnapshot dataSnapshot) {                     adapter.remove((String) dataSnapshot.kid("title").getValue());                 }                  @Override                 public void onChildMoved(DataSnapshot dataSnapshot, String s) {}                  @Override                 public void onCancelled(DatabaseError databaseError) {}             });         }     }      private void loadLogInView() {         Intent intent = new Intent(this, LogInActivity.form);         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);         startActivity(intent);     } }        

Y'all create a reference to the root node of the database with FirebaseDatabase.getInstance().getReference(). Yous so set a listener on the Add New Item push button that saves data to Firebase when clicked.

In that location are 4 methods for writing information to the Firebase Realtime Database:

  • setValue() writes or replaces information to a defined path, such as users/<user-id>/<username>. Y'all can utilize setValue() to save dissimilar types of data to a Firebase database: String, Long, Double, Boolean, Map<Cord, Object>, List<Object>, custom Java objects.
  • push() adds to a list of data. Every time you call push(), Firebase generates a unique key that can also be used every bit a unique identifier, such every bit user-posts/<user-id>/<unique-post-id>.
  • updateChildren() updates some of the keys for a defined path without replacing all of the data.
  • runTransaction() update complex information that could be corrupted by concurrent updates.

In our code, information is saved with:

String championship = etTitle.getText().toString(); Particular particular = new Item(title ); db.child("users").child(userId).child("items").push().setValue(item);        

.kid gets a reference to the specified node if it exists or creates it if it doesn't be. The above will relieve the entered text at the path /users/<user-id>/items/<item-id>/title.

.push button() generates a new kid location using a unique fundamental. You use it to generate a unique key for each item added.

.setValue() writes or replaces data to the defined path.

To think data from Firebase, add together a listener to the database reference with addChildEventListener(). Y'all can heed for the following types of events that retrieve information:

  • ValueEventListener: onDataChange() reads and listens for changes to the entire contents of a path.
  • ChildEventListener: onChildAdded() retrieves lists of items or listen for additions to a list of items. Suggested use with onChildChanged() and onChildRemoved() to monitor changes to lists.
  • ChildEventListener: onChildChanged() listens for changes to the items in a list. Use with onChildAdded() and onChildRemoved() to monitor changes to lists.
  • ChildEventListener: onChildRemoved() listens for items beingness removed from a list. Use with onChildAdded() and onChildChanged() to monitor changes to lists.
  • ChildEventListener: onChildMoved() listens for changes to the lodge of items in an ordered list. onChildMoved() events e'er follow the onChildChanged() event that caused the item's order to change (based on your current society-by method).

The listener receives a DataSnapshot, which is a snapshot of the data. A snapshot is a picture of the data at a particular location in a Firebase database at a single indicate in fourth dimension. Calling getValue() on a snapshot returns the Java object representation of the information. The possible types returned past getValue() are Boolean, String, Long, Double, Map<Cord, Object>, and Listing<Object>. If no data exists at the location, the snapshot will return cipher and it's a good idea to cheque for zilch earlier you try using the data. Finally, add together the retrieved data to the list view.

Also we set an onClick listener on the ListView and queries the database when an item is tapped. It searches the Firebase database for the item with a title equal to the string at the tapped location. With a more complex app you might desire to search for something that is unique to the object, like an id. It and so removes the start occurrence of the item from the database. The listing view is automatically updated.

Create menu in res/menu/menu_main.xml and add item with the following Logout item.

<item     android:id="@+id/action_logout"     android:orderInCategory="100"     android:title="@string/action_logout"     app:showAsAction="never"/>        

Open MainActivity and add following snippet.

          @Override     public boolean onCreateOptionsMenu(Carte menu) {         getMenuInflater().inflate(R.menu.menu_main, bill of fare);         return super.onCreateOptionsMenu(carte);     }      @Override     public boolean onOptionsItemSelected(MenuItem particular) {         switch (item.getItemId()) {             example R.id.action_logout:                 auth.signOut();                 loadLogInView();                 break;             default:                 break;         }         render true;     }        

This menu item will logout the user.

If yous run the app and add together some items, they will be added to the listing and to the database.

android_firebase_add.png

Authenticate Using Facebook Login

Head over to Facebook Developer website to create your app and get your application ID by clicking on the Add together a new app button. You lot can read detailed educational activity in Android Facebook SDK integration tutorial .

To enable authenticate using Facebook in Firebase follow these steps

  1. Become to your Firebase project panel.
  2. Click Authentication under Develop department.
  3. Select Sign-in method tab and enable Facebook Sign-In past giving Facebook App Id and App Hugger-mugger.

To start working with Facebook authentication we need to add Firebase Authentication dependencies to our android project. Delight add the following dependency in your module-level gradle and compile.

compile 'com.google.firebase:firebase-auth:ten.0.ane' compile 'com.facebook.android:facebook-android-sdk:[four,5)'        

Example of layout

<?xml version="1.0" encoding="utf-8"?> <LinearLayout     xmlns:android="http://schemas.android.com/apk/res/android"     android:layout_width="match_parent"     android:layout_height="match_parent"     android:orientation="vertical"     android:padding="16dp">      <com.facebook.login.widget.LoginButton         android:id="@+id/btnLogin"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_centerInParent="truthful"         />  </LinearLayout>        

Example of Activity.

public class FacebookActivity extends AppCompatActivity {     private TextView tvStatus;     private LoginButton btnLogin;     private CallbackManager callbackManager;     private FirebaseAuth firebaseAuth;     Cord TAG = "DBG";      @Override     protected void onCreate(Package savedInstanceState) {         super.onCreate(savedInstanceState);         callbackManager = CallbackManager.Factory.create();         setContentView(R.layout.activity_facebook);          firebaseAuth = FirebaseAuth.getInstance();          btnLogin = (LoginButton)findViewById(R.id.btnLogin);         btnLogin.setReadPermissions("public_profile,user_photos,user_birthday,user_work_history");         btnLogin.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {             @Override             public void onSuccess(LoginResult loginResult) {                 AccessToken token = loginResult.getAccessToken();                 Log.d(TAG, "onSuccess: " + token.getUserId());                 handleFacebookAccessToken(loginResult.getAccessToken());             }              @Override             public void onCancel() {                 Log.d(TAG, "onCancel: Login attempt canceled.");             }              @Override             public void onError(FacebookException eastward) {                 Log.d(TAG, "onError: Login endeavour failed.");             }         });          if (AccessToken.getCurrentAccessToken() != nil) {             goMainScreen();         }     }      private void handleFacebookAccessToken(AccessToken accessToken) {         AuthCredential credential = FacebookAuthProvider.getCredential(accessToken.getToken());         firebaseAuth.signInWithCredential(credential).addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {             @Override             public void onComplete(@NonNull Task<AuthResult> task) {                 Log.d(TAG, "onComplete: " + task.getResult().getUser().getUid());                  if(!chore.isSuccessful())                     Toast.makeText(getApplicationContext(), "Error login", Toast.LENGTH_LONG).show();                 else                     Toast.makeText(getApplicationContext(), "Successful login", Toast.LENGTH_LONG).evidence();             }         }).addOnFailureListener(new OnFailureListener() {             @Override             public void onFailure(@NonNull Exception east) {                 e.printStackTrace();             }         });     }      @Override     protected void onActivityResult(int requestCode, int resultCode, Intent data) {         callbackManager.onActivityResult(requestCode, resultCode, data);     }      public void goMainScreen(){         Intent intent = new Intent(this, ItemsActivity.grade);         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |             Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);         startActivity(intent);     } }        

How to run several queries sequentially

Starting with Google Play services version nine.0.0, you tin use a Tasks API which provides

  • asynchronous method calls, similar to PendingResult in previous versions of Google Play Services
  • concatenation tasks i after another
  • enable the executor, etc to be specified for each chore and thread switching very easily (between background and chief thread).
  • allow errors to be captured and dealt with at a convenient time

Tasks API would be expert for background piece of work that returns a single value such every bit general network requests, reading files off disk, etc.

If you lot desire to work with the Task API without having to integrate Firebase into your app, you can get the library with a dependency in your build.gradle:

compile 'com.google.android.gms:play-services-tasks:ix.6.i'        

Just, if yous are integrating Firebase, you'll get this library included for free, and so no need to call it out specifically in that instance.

So, instead of nesting listeners, you can create a sequence of tasks.

The result will be sent to addOnSuccessListener if all tasks execute successfully. If any of them fail during the use case execution, the sequence will be aborted and the exception is passed to addOnFailureListener.

Let's create simple Task

public Job<String> getName() {     final TaskCompletionSource<Cord> tcs = new TaskCompletionSource<>();     tcs.setResult("John");     //tcs.setException(Exception());     render tcs.getTask(); }        

Allow's execute it

// Activity activity = MainActivity.this;  // first approach getName().addOnSuccessListener(action, new OnSuccessListener<String>() {     @Override     public void onSuccess(Cord proper name) {         Log.d(TAG, "onSuccess: " + name);     } });  // second approach getName().addOnCompleteListener(activity, new OnCompleteListener<String>() {     @Override     public void onComplete (Chore task) {         if (chore.isSuccessful()) {             // exercise something with proper name ...             String name = (String) chore.getResult();             Log.d("Www", "onComplete: " + proper noun);         } else {             // handle the failure ...             Exception e = task.getException();         }     } });        

And so, with OnCompleteListener, y'all tin can have a single listener that handles both success and failure, and you detect out which ane by calling isSuccessful() on the Chore object passed to the callback. Practically speaking, this is functionally equivalent to registering both an OnSuccessListener and an OnFailureListener. The style y'all choose is generally a matter of preference.

Besides we can run several tasks sequentially. Let'south create GetUser and GetPhoto tasks.

class GetUser implements Continuation<Void, Task<Cord>> {     @Override     public Task<String> and so(Task<Void> task) {         final TaskCompletionSource<String> tcs = new TaskCompletionSource();          //tcs.setException(fault.toException());         tcs.setResult("John");         return tcs.getTask();     } }  class GetPhoto implements Continuation<Cord, Task<String>> {     @Override     public Task<String> and so(Task<String> task) {         final TaskCompletionSource<Cord> tcs = new TaskCompletionSource();          String name = task.getResult();          //tcs.setException(error.toException());         tcs.setResult("John's photos");         render tcs.getTask();     } }        

Run it sequentially with following control

Tasks.<Void>forResult(null)         .continueWithTask(new GetUser())         .continueWithTask(new GetPhoto())         .addOnSuccessListener(action, new OnSuccessListener<Cord>() {             @Override             public void onSuccess(String southward) {                 Log.d("WWW", "onSuccess!!!!");             }         });        

The primary difference between continueWith and continueWithTask is ane of the generic types of the Continuation you pass to it.

You can think of a Continuation as something that converts some input blazon to some output type. If you lot define a Continuation<IN, OUT>, where IN is the input type passed to its and so method via a Task<IN>, and OUT is the blazon that method returns.

When calling continueWith, you pass a Continuation<IN, OUT>, and the then method is expected to compute and render the OUT value given a Task<IN> value every bit input. You lot might choose to do this if you don't have whatever blocking piece of work to do for the conversion, such as reducing an integer array to the sum of its elements or counting the number of words in a Cord.

When calling continueWithTask, you pass a Continuation<IN, Chore<OUT>>, and the and so method is expected to return a Task<OUT> that eventually generates the OUT value, given the IN value as input. Yous might choose this if y'all are able to consul the conversion work to an existing reusable Task. continueWithTask is perfect when you desire to utilize a Continuation and a TaskCompletionSource together.

Practically speaking, you aren't required to choose one or the other to do your piece of work. It'south a matter of preferred style, or if you have a nice Task gear up to delegate your conversation rather than a Continuation. Typically you just apply a Continuations if y'all have a pipeline of conversions to concatenation together.

The Task API provides a couple methods (whenAll) to aid you lot know when several Tasks are all consummate. These static utility methods create a new Job that gets triggered in response to the completion of a collection of Tasks that you provide.

Let's create getName and getPhoto tasks.

public Task<String> getName() {     final TaskCompletionSource<Cord> tcs = new TaskCompletionSource<>();     tcs.setResult("John");     //tcs.setException(Exception());     return tcs.getTask(); }  public Task<String> getPhoto() {     final TaskCompletionSource<String> tcs = new TaskCompletionSource<>();     tcs.setResult("John's photos");     //tcs.setException(Exception());     return tcs.getTask(); }        

Collect all tasks to array

Chore<?>[] tasks = new Task[] {         getName(),         getPhoto() };        

As well create job that will offset afterwards all.

class FinishTask implements Continuation<Void, Task<Void>> {     @Override     public Chore<Void> then(@NonNull Task<Void> task) throws Exception {         concluding TaskCompletionSource<Void> tcs = new TaskCompletionSource<>();          if (job.isSuccessful()) {             Log.d(TAG, "then: isSuccessful" + proper noun);             tcs.setResult(cipher);         } else {             Log.d(TAG, "then: NOT isSuccessful");         }          render tcs.getTask();     } }        

Run with following control

Tasks.whenAll(tasks).continueWithTask(new FinishTask()).addOnSuccessListener(activeness, new OnSuccessListener<String>() {         @Override         public void onSuccess(String s) {             Log.d(TAG, "onSuccess!!!!");         }     });        

How to fetch list of items and combine them via RxJava2

For this purpose nosotros tin RxJava2.

You tin place following snippet somewhere in Utils.java

public static Observable<List<Particular>> getItems(String id) {     return Appreciable.create(new ObservableOnSubscribe<List<Item>>() {         @Override         public void subscribe(ObservableEmitter<Listing<Item>> east) throws Exception {             String itemIndex = String.format("%s_%d", id, Item.STATE_ACCEPT);              ValueEventListener listener = new ValueEventListener() {                 @Override                 public void onDataChange(DataSnapshot dataSnapshot) {                      List<Detail> items = new ArrayList<>();                      if (dataSnapshot.getChildrenCount() > 0) {                         for (DataSnapshot ds : dataSnapshot.getChildren()) {                             Item item = ds.getValue(Detail.grade);                             items.add together(detail);                         }                         due east.onNext(items);                         due east.onComplete();                     } else {                         e.onNext(Collections.<Detail>emptyList());                     }                 }                  @Override                 public void onCancelled(DatabaseError databaseError) {                     e.onError(new FirebaseException(databaseError.getMessage()));                 }             };              Query query = Utils.getDB().child(Constants.FIREBASE_ITEMS_DB).orderByChild("itemIndex").equalTo(itemIndex);             query.addListenerForSingleValueEvent(listener);         }     }); }        

You lot can use it somewhere in Activeness.

Appreciable<List<Particular>> itemA = Utils.getItems(itemAId); Observable<List<Item>> itemB = Utils.getItems(itemBId);  Observable.zip(itemA, itemB, (a, b) -> {     List<Item> items = new ArrayList<>();     items.addAll(a);     items.addAll(b);     return items; }).subscribeOn(Schedulers.io())     .observeOn(AndroidSchedulers.mainThread())     .subscribe((items) -> {         for (Item particular : items) {             ...         }     });        

You tin can spy more examples here.

Useful links

  • Using Firebase Analytics
  • How to Create an Android Chat App Using Firebase

smithwanexpeck.blogspot.com

Source: https://en.proft.me/2017/03/17/android-firebase-tutorial/

0 Response to "How to Read Data From Firebase Database"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel