Home > Net >  How to get an error message when data could not be written into the Firebase Database using Android
How to get an error message when data could not be written into the Firebase Database using Android

Time:11-07

I am using Android and I would like to store some data in the Firebase Realtime Database. Strangely, sometimes this works and sometimes it does not. I thought that this might have something to do with my WLAN connection which is not always good, but even if the WLAN connection is good sometimes data can be written into the Firebase Database, and sometimes it just does not work.

Anyway, what I would like to have is a message to the user that the data has not been written into the Firebase Database if this was the case in form of a toast. For this purpose I have the following Java Fragment:

package com.example.td.bapp;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.database.Cursor;
import android.os.Bundle;
import android.text.InputType;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.navigation.Navigation;

import com.example.td.bapp.databinding.TestFragmentBinding ;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import java.util.concurrent.atomic.AtomicBoolean;


    public class TestFragment extends Fragment implements View.OnClickListener {
    
    
    
        @Override
        public void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
        }
    
        @Nullable
    
        private TestFragmentBinding binding;
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    
            binding = TestFragmentBinding.inflate(inflater, container, false);
    
    
            /*
            Set onClickListeners to the buttoms
             */
    
            binding.orderingButton.setOnClickListener(this);
    
            return binding.getRoot();
    
        }
    
        public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
    
    
    
        }
    
        @Override
        public void onClick(View view) {
    
            if(view.getId() == R.id.ordering_button) {
    
    
                /*
                Write data into the Firebase DB
                 */
    
                long currentTimeMillis = System.currentTimeMillis();
                SimpleDateFormat sdf1 = new SimpleDateFormat("dd-MM-yy");
                sdf1.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
                SimpleDateFormat sdf2 = new SimpleDateFormat("HH-mm-ss");
                sdf1.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
    
    
                DatabaseReference rootRef = FirebaseDatabase.getInstance("https://drink-server-db-default-rtdb.europe-west1.firebasedatabase.app").getReference();
                DatabaseReference ordersRef = rootRef.child("orders");
                String id ="table_"   MainActivity.tableNumber   "_order_"   MainActivity.orderNumberOfTheSession   "_date_"   sdf1.format(new Date())   "_time_"   sdf2.format(new Date());
                String name1 = "Test_1";
                String name2 = "Test_2";
                FirebaseDBItem_Order currentOrder = new FirebaseDBItem_Order(name1, name2);
                Log.e("LogTag", "Before write into DB");
                ordersRef.child(id).setValue(currentOrder).addOnCompleteListener(new OnCompleteListener<Void>() {
                    @Override
                    public void onComplete(@NonNull Task<Void> task) {
                        if (task.isSuccessful()) {
                            Log.e("dbTAG",  "Data successfully written.");
                            int duration = Toast.LENGTH_LONG;
                            Toast toast = Toast.makeText(getContext(), getString(R.string.message_orderSubmittedSuccessfully), duration);
                            toast.setGravity(Gravity.CENTER, 0, 0);
                            toast.show();
                        }
                        else {
                            Log.e("dbTAG", task.getException().getMessage());
                            int duration = Toast.LENGTH_LONG;
                            Toast toast = Toast.makeText(getContext(), getString(R.string.message_orderSubmittedNotSuccessfully), duration);
                            toast.setGravity(Gravity.CENTER, 0, 0);
                            toast.show();
                        }
                    }
                });
    
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Log.e("LogTag", "After write into DB");
    
    
                Navigation.findNavController(getView()).navigate(TestFragmentDirections.actionFRCocktailToFRMenu());
    
            }
    
    
        }
    
    
    }

If the data is written successfully into the Firebase Database the toast is displayed and I get the correct dbTAG and LogTag messages:

E/LogTag: Before write into DB

E/LogTag: After write into DB

E/dbTAG: Data successfully written.

However, when the data is not successfully written into the Firebase Database, I just don't get any message from the dbTAG of the onComplete method and no new entry can be found in the database. I just get the LogTag messages:

E/LogTag: Before write into DB

E/LogTag: After write into DB

Now actually I have 2 questions:

  1. Why sometimes the data can be written into the Firebase Database and sometimes not and why this seems to happen "randomly"? Can you think of some reasons?
  2. More importantly: How can I get an error message when the data could not be written into the Firebase Database such that I can inform the user? And related to this: Why do I not get a Log.e("dbTAG", task.getException().getMessage()); message when the data was not successfully written into the Firebase Database? So the else branch of the onComplete method is not executed when the data is not successfully stored.

If you need any further information, please let me know.

CodePudding user response:

Why sometimes the data can be written into the Firebase Database and sometimes not and why this seems to happen "randomly"? Can you think of some reasons?

Most likely this it's because of the lack of internet connection. To solve this, you should enable offline persistence. In Java code, this can be done using the following line:

FirebaseDatabase.getInstance().setPersistenceEnabled(true);

According to the docs:

Firebase applications work even if your app temporarily loses its network connection.

Firebase apps automatically handle temporary network interruptions. Cached data is available while offline and Firebase resends any writes when network connectivity is restored.

And to answer your second question:

More importantly: How can I get an error message when the data could not be written into the Firebase Database such that I can inform the user? And related to this: Why do I not get a Log.e("dbTAG", task.getException().getMessage()); message when the data was not successfully written into the Firebase Database? So the else branch of the onComplete method is not executed when the data is not successfully stored.

You are handling the errors in a correct way using:

Log.e("dbTAG", task.getException().getMessage());

You'll get an error message, when there is a problem with writing the data, meaning the write operation is rejected by the Firebase severs, for example, when you have improper security rules.

Please also note, that Firebase Realtime Database SDK doesn't throw an Exception when there is no internet connection, and it makes sense since Firebase Realtime Database is designed to work offline. Behind the scenes, Firebase Realtime Database SDK tries to reconnect until the devices regain connectivity. However, it will indeed throw an Exception, when Firebase servers reject the request due to a security rule issue.

  • Related