当前位置: 首页 > 知识库问答 >
问题:

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

邓驰
2023-03-14

我正在使用Android,我想在Firebase实时数据库中存储一些数据。奇怪的是,这有时有效,有时无效。我认为这可能与我的WLAN连接有关,虽然WLAN连接并不总是很好,但即使WLAN连接很好,有时数据也可以写入Firebase数据库,有时甚至无法正常工作。

无论如何,我想要的是给用户一条消息,即数据尚未写入Firebase数据库,如果这是以祝酒词的形式出现的情况。为此,我有以下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());
    
            }
    
    
        }
    
    
    }

如果数据成功写入Firebase数据库,则会显示toast,并获得正确的dbTAG和LogTag消息:

E/LogTag:写入DB之前

E/LogTag:写入数据库后

E/dbTAG:数据写入成功。

然而,当数据没有成功写入Firebase数据库时,我只是没有从onComplete方法的dbTAG中获得任何消息,并且在数据库中找不到新条目。我刚收到LogTag消息:

E/LogTag:写入DB之前

E/LogTag:写入数据库后

现在我有两个问题:

  1. 为什么有时数据可以写入Firebase数据库,有时则不能,为什么这似乎是“随机”发生的?你能想出一些原因吗
  2. 更重要的是:当数据无法写入Firebase数据库时,如何获得错误消息,以便通知用户?与此相关的是:为什么我不获取日志。e(“dbTAG”,task.getException()。getMessage()) 数据未成功写入Firebase数据库时的消息?因此,当数据未成功存储时,不会执行onComplete方法的else分支

如果你需要任何进一步的信息,请告诉我。

共有1个答案

邴奇逸
2023-03-14

为什么有时数据可以写入Firebase数据库,有时不能,为什么这似乎是“随机”发生的?你能想到一些原因吗?

很可能是因为缺少互联网连接。要解决这个问题,您应该启用离线持久性。在Java代码中,可以使用以下行来完成:

FirebaseDatabase.getInstance().setPersistenceEnabled(true);

根据文件:

即使您的应用暂时失去网络连接,Firebase应用程序也能正常工作。

Firebase应用程序自动处理临时网络中断。缓存数据在脱机时可用,Firebase在恢复网络连接时会重新发送任何写操作。

回答你的第二个问题:

更重要的是:当数据无法写入Firebase数据库时,如何获得错误消息,以便通知用户?与此相关的是:为什么我没有日志。e(“dbTAG”,task.getException()。getMessage());数据未成功写入Firebase数据库时的消息?因此,当数据未成功存储时,onComplete方法的else分支不会执行。

您正在使用以下方法以正确的方式处理错误:

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

当写入数据出现问题时,您将收到一条错误消息,这意味着写入操作被Firebase服务器拒绝,例如,当您有不正确的安全规则时。

还请注意,Firebase实时数据库SDK在没有internet连接的情况下不会引发异常,这很有意义,因为Firebase实时数据库设计为脱机工作。在幕后,Firebase实时数据库SDK尝试重新连接,直到设备重新连接。但是,当Firebase服务器由于安全规则问题拒绝请求时,它确实会引发异常。

 类似资料:
  • 我设法将数据插入身份验证,但无法插入数据库: 代码: 错误: E/AndroidRuntime:致命异常:主进程:com。实例budgetingapp,PID:11507 java。lang.RuntimeException:在类androidx上找到了名称getText的冲突获取程序。appcompat。小装置。AppCompativeText位于com。谷歌。火基。消防商店。util。Cust

  • 我正在尝试用Firebase制作一个简单的Android应用程序。 目前,我只是试图从Firebase实时保存用户数据库。但由于某种原因它不起作用。另一方面,身份验证工作完美。 数据库本身没有显示任何内容。它总是显示“null” 我一直在关注这个YouTube教程,并一直在做一些类似的事情。 当我尝试创建一个用户并将其发送到数据库时,运行的程序没有给出任何答案。我有一个进度条,一旦setValue

  • 我正在尝试获取我的用户名,并在应用程序打开时向他/她问好。但我无法根据某个用户的uid获取数据。当我运行应用程序时,祝酒词从未真正出现。 数据库结构 密码

  • 首先,我很抱歉我的英语,我希望你能理解。这是我的第一个android应用程序,我尝试使用Firebase进行身份验证和数据库。身份验证工作正常,但我不能读写实时数据库。以下是我的数据库规则和结构: 我试图将数据库中的数据添加到reclyclerview中,但我的代码止步于AddValueEventListener。然后我尝试添加一个简单的数据到数据库,但它也不起作用。我也尝试将相同的代码放入一个活

  • 我正在尝试将有关集合用户中注册用户的数据写入我的Cloud Firestone用户,当然它必须与授权中的UID代码相关联(注册/登录系统正常工作并在我的Firebase中编写auth)。 XML注册按钮: JAVA寄存器: 。。。 。。。 在Cloud Firestone中,我刚刚创建了集合用户。我注意到在工具中 ✓ 已连接 但即使我已经点击并似乎构建正确,底部的“将云Firestone添加到你的