MainActivity.java (Cont.)

public void onCancelled( DatabaseError error ) {
Instances of DatabaseError are passed to callbacks when an operation failed. They contain a description of the specific error that occurred. The method onCancelled will be triggered in the event that this listener either failed at the server, or is removed as a result of the security and Firebase Database rules.

userId = mFirebaseDatabase.push( ).getKey( );
The method push adds to a list of data. Every time you call push, Firebase generates a unique key that can also be used as a unique identifier. The method getKey returns the last token in the location pointed to by this reference or null if this reference points to the database root.

User user = new User( name, email );
mFirebaseDatabase.child(userId).
          setValue(user);

mFirebaseDatabase.child(userId).
          child("name").setValue(name);
The method child gets a reference to location relative to this one.

MyFirebase\app\java\com\wenchen\myfriebase\MainActivity.java
 package com.wenchen.myfirebase

 import android.os.Bundle;
 import androidx.appcompat.app.AppCompatActivity;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.View;
 import android.widget.Button;
 import android.widget.EditText;
 import android.widget.TextView;

 import com.google.firebase.database.DataSnapshot;
 import com.google.firebase.database.DatabaseError;
 import com.google.firebase.database.DatabaseReference;
 import com.google.firebase.database.FirebaseDatabase;
 import com.google.firebase.database.ValueEventListener;

 public class MainActivity extends AppCompatActivity {
   private static final String TAG = MainActivity.class.getSimpleName( );
   private TextView txtDetails;
   private EditText inputName, inputEmail;
   private Button btnSave;
   private DatabaseReference mFirebaseDatabase;
   private FirebaseDatabase mFirebaseInstance;
   private String userId;

   @Override
   protected void onCreate( Bundle savedInstanceState ) {
     super.onCreate( savedInstanceState );
     setContentView( R.layout.activity_main );
     // Displaying toolbar icon
     getSupportActionBar( ).setDisplayShowHomeEnabled( true );
     getSupportActionBar( ).setIcon( R.mipmap.ic_launcher );

     txtDetails = (TextView) findViewById( R.id.txt_user );
     inputName  = (EditText) findViewById( R.id.name );
     inputEmail = (EditText) findViewById( R.id.email );
     btnSave    = (Button)   findViewById( R.id.btn_save );

     mFirebaseInstance = FirebaseDatabase.getInstance( );
     // Getting reference to 'users' node
     mFirebaseDatabase = mFirebaseInstance.getReference( "users" );
     // Storing app title to 'app_title' node
     mFirebaseInstance.getReference( "app_title" ).setValue( "Realtime Database" );

     // app_title change listener
     mFirebaseInstance.getReference( "app_title" ).addValueEventListener(
       new ValueEventListener( ) {
         @Override
         public void onDataChange( DataSnapshot dataSnapshot ) {
           Log.e( TAG, "App title updated" );
           String appTitle = dataSnapshot.getValue( String.class );
           // Updating toolbar title
           getSupportActionBar( ).setTitle( appTitle );
         }
         @Override
         public void onCancelled( DatabaseError error ) {
           // Failed to read value
           Log.e( TAG, "Failed to read app title value.", error.toException( ) );
         }
       }
     );
     // Saving or updating the user
     btnSave.setOnClickListener( 
       new View.OnClickListener( ) {
         @Override
         public void onClick( View view ) {
           String name  = inputName.getText(  ).toString( );
           String email = inputEmail.getText( ).toString( );
           // Checking for already existed userId
           if ( TextUtils.isEmpty( userId ) )  createUser( name, email );
           else  updateUser( name, email );
         }
       }
     );
     toggleButton( );
   }
   // Changing button text
   private void toggleButton( ) {
     if ( TextUtils.isEmpty( userId ) )  btnSave.setText( "Save" );
     else  btnSave.setText( "Update" );
   }
   //
   //   Creating new user node under 'users'
   //
   private void createUser( String name, String email ) {
     // TODO
     // In real apps this userId should be fetched by using auth
     if ( TextUtils.isEmpty( userId ) )
       userId  = mFirebaseDatabase.push( ).getKey( );
     User user = new User( name, email );
     mFirebaseDatabase.child( userId ).setValue( user );
     addUserChangeListener( );
   }
   //
   //   User data change listener
   //
   private void addUserChangeListener( ) {
     mFirebaseDatabase.child( userId ).addValueEventListener( 
       new ValueEventListener( ) {
         @Override
         public void onDataChange( DataSnapshot dataSnapshot ) {
           User user = dataSnapshot.getValue( User.class );
           // Check for null
           if ( user == null ) {
             Log.e( TAG, "User data is null!" );
             return;
           }
           Log.e( TAG, "User data is changed!" + user.name + ", " + user.email );
           // Displaying newly updated name and email
           txtDetails.setText( user.name + ", " + user.email );
           // Clearing edit text
           inputEmail.setText( "" );
           inputName.setText ( "" );
           toggleButton( );
         }
         @Override
         public void onCancelled( DatabaseError error ) {
           // Failed to read value
           Log.e( TAG, "Failed to read user", error.toException( ) );
         }
       }
     );
   }
   private void updateUser( String name, String email ) {
     // Updating the user via child nodes
     if ( !TextUtils.isEmpty( name ) )
       mFirebaseDatabase.child( userId ).child( "name"  ).setValue( name );
     if ( !TextUtils.isEmpty( email ) )
       mFirebaseDatabase.child( userId ).child( "email" ).setValue( email );
   }
 }