简体   繁体   English

无法使用 Android 将数据写入 Firebase 数据库时如何获取错误消息

[英]How to get an error message when data could not be written into the Firebase Database using Android

I am using Android and I would like to store some data in the Firebase Realtime Database.我正在使用 Android,我想在 Firebase 实时数据库中存储一些数据。 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.我认为这可能与我的 WLAN 连接有关,这并不总是好的,但即使 WLAN 连接良好,有时数据也可以写入 Firebase 数据库,有时它只是不起作用。

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.无论如何,我想要给用户的消息是,如果是敬酒形式的情况,则数据尚未写入 Firebase 数据库。 For this purpose I have the following Java Fragment:为此,我有以下 Java 片段:

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:如果数据成功写入 Firebase 数据库,则会显示 toast 并且我会收到正确的 dbTAG 和 LogTag 消息:

E/LogTag: Before write into DB E/LogTag:写入数据库前

E/LogTag: After write into DB E/LogTag:写入数据库后

E/dbTAG: Data successfully written. E/dbTAG:数据写入成功。

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.但是,当数据没有成功写入 Firebase 数据库时,我只是没有从 onComplete 方法的 dbTAG 收到任何消息,并且在数据库中找不到新条目。 I just get the LogTag messages:我刚收到 LogTag 消息:

E/LogTag: Before write into DB E/LogTag:写入数据库前

E/LogTag: After write into DB E/LogTag:写入数据库后

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"?为什么有时数据可以写入 Firebase 数据库而有时不能,为什么这似乎是“随机”发生的? 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?更重要的是:当数据无法写入 Firebase 数据库时,我如何获得错误消息以便通知用户? And related to this: Why do I not get a Log.e("dbTAG", task.getException().getMessage());与此相关:为什么我没有得到Log.e("dbTAG", task.getException().getMessage()); message when the data was not successfully written into the Firebase Database?数据未成功写入 Firebase 数据库时的消息? So the else branch of the onComplete method is not executed when the data is not successfully stored.所以当数据没有成功存储时, onComplete方法的else分支不会被执行。

If you need any further information, please let me know.如果您需要任何进一步的信息,请告诉我。

Why sometimes the data can be written into the Firebase Database and sometimes not and why this seems to happen "randomly"?为什么有时数据可以写入 Firebase 数据库而有时不能,为什么这似乎是“随机”发生的? 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:在 Java 代码中,这可以使用以下行来完成:

FirebaseDatabase.getInstance().setPersistenceEnabled(true);

According to the docs:根据文档:

Firebase applications work even if your app temporarily loses its network connection.即使您的应用暂时失去网络连接,Firebase 应用也能正常工作。

Firebase apps automatically handle temporary network interruptions. Firebase 应用会自动处理临时网络中断。 Cached data is available while offline and Firebase resends any writes when network connectivity is restored.离线时缓存数据可用,Firebase 会在网络连接恢复后重新发送任何写入。

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?更重要的是:当数据无法写入 Firebase 数据库时,我如何获得错误消息以便通知用户? And related to this: Why do I not get a Log.e("dbTAG", task.getException().getMessage());与此相关:为什么我没有得到 Log.e("dbTAG", task.getException().getMessage()); message when the data was not successfully written into the Firebase Database?数据未成功写入 Firebase 数据库时的消息? So the else branch of the onComplete method is not executed when the data is not successfully stored.所以当数据没有成功存储时,onComplete方法的else分支不会被执行。

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.当写入数据出现问题时,您会收到一条错误消息,这意味着 Firebase 服务器会拒绝写入操作,例如,当您的安全规则不正确时。

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.另请注意,Firebase 实时数据库 SDK 在没有互联网连接时不会抛出异常,这是有道理的,因为 Firebase 实时数据库旨在离线工作。 Behind the scenes, Firebase Realtime Database SDK tries to reconnect until the devices regain connectivity.在幕后,Firebase 实时数据库 SDK 会尝试重新连接,直到设备重新连接。 However, it will indeed throw an Exception, when Firebase servers reject the request due to a security rule issue.但是,当 Firebase 服务器由于安全规则问题拒绝请求时,它确实会抛出异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如果使用android studio在firebase中缺少孩子,如何设置错误消息 - How to set error message if a child is missing in firebase using android studio Android Studio如何从Firebase数据库获取数据? - Android Studio how to get data from the Firebase database? 如何从Android中的Firebase数据库中按参数获取数据? - How to get data by parameter from Firebase database in Android? 如何从Android中的firebase实时数据库中获取最后一个数据 - How to get the last data from realtime database of firebase in Android android studio firebase 数据库:如何从子子节点获取数据 - android studio firebase database: how to get data from sub child 如何使用Firebase数据库在Android中绘制多个数据集的图形? - How to graph multiple data sets in Android using Firebase database? 在RecyclerView中获取随机数据Android Firebase数据库 - Get random data android firebase database in RecyclerView Firebase实时数据库:使用AddChildEventListener时如何获取ChildrenCount? - Firebase realtime database:How to get ChildrenCount when using AddChildEventListener? 使用Firebase UI数据库绑定到Recycler View(Android)时,Firebase不会检索数据 - Firebase not retrieving data when binding using Firebase UI Database to Recycler View (Android) 在Android中使用openOrCreateDatabase时出错(无法打开数据库) - Error using openOrCreateDatabase in android (Could not open database)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM