正在从数据库中获取数据,但仍然给出 NullPointerException

Posted

技术标签:

【中文标题】正在从数据库中获取数据,但仍然给出 NullPointerException【英文标题】:Data is being fetched from DB but still giving NullPointerException 【发布时间】:2019-04-11 01:28:42 【问题描述】:

我正在处理MapActivity,我从我的数据库中获取供应商信息并将其存储在Supplier 对象中。我正在调用两个函数 fetchSupplier()FetchStationInfo(),其中第一个获取供应商信息并存储到 Object 中,第二个使用它。所以,问题是当我单独运行fetchSupplier() 时,数据会被获取并存储在我的对象中,但是当我在fetchSupplier() 之后调用这两个函数,即FetchStationInfo() 时,它会在FetchStationInfo() 中给出一个空指针异常。以下是我调用函数的方式:

@Override
public void onMapReady(GoogleMap googleMap) 
    mMap = googleMap;
    fetchSupplier();
    fetchStationInfo();

我的两个功能:

private void fetchSupplier()
    String uid = mAuth.getUid();
    mDatabase = FirebaseDatabase.getInstance().getReference()
            .child("SUPPLIERS").child(uid);

    mDatabase.addListenerForSingleValueEvent(new ValueEventListener() 
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) 
            supplier = dataSnapshot.getValue(Supplier.class);
            Log.i("USER FETCH COMPLETE ","["+supplier.getName()+"]");
        
        @Override
        public void onCancelled(DatabaseError databaseError) 
            Log.i("FETCHING USER [ERROR] ",databaseError.getMessage());
        
    );


private void fetchStationInfo()
    //Exception is here in this line where I am calling `getStation_id()`
    mDatabase = FirebaseDatabase.getInstance().getReference()
            .child("STATIONS").child(supplier.getStation_id());

    mDatabase.addListenerForSingleValueEvent(new ValueEventListener() 
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) 
            station = dataSnapshot.getValue(Station.class);
            Log.i("STATION FETCH COMPLETE ","["+station.getName()+"]");
        
        @Override
        public void onCancelled(DatabaseError databaseError) 
            Log.i("STATION FETCH [ERROR] ",databaseError.getMessage());
        
    );

我的对象是全局声明的。已经工作了几个小时,但无法修复它。我的火力基地结构:

【问题讨论】:

请也添加您的 firebase 结构,以便我们查看从数据库中获取值是否有问题 @PradyumanDixit 我认为结构没有任何问题,但我只是编辑了我的答案。 只是好奇:是否有任何供应商拥有多个“站”? (从您的数据示例来看,您的数据结构看起来很平坦。)如果每个供应商确实只有一个工作站,那么确实没有理由将数据分成两个表。 @Barns 这就像每个供应商确实有一个站点,但每个站点将有多个供应商。所以我在这里以某种方式使用参考键和东西的概念。对不起,如果我很愚蠢,这是我第一次使用 NoSql 数据库。另外还有很多要补充的。 一点也不!你不是“愚蠢”!从关系数据库背景转向 NoSQL 概念并不容易!而且我在 NoSQL 方面的经验非常有限。我只是想看看结合这两个“表”是否有任何潜在的优势。继续编码!祝你好运! 【参考方案1】:

问题是fetchStationInfo() 试图从fetchSupplier() 获取supplier

请记住,Firebase 调用是异步的,您在获取供应商时会尝试获取它。

所以,如果你这样做

public void onMapReady(GoogleMap googleMap) 
    mMap = googleMap;
    fetchSupplier();
    fetchStationInfo();

这两个方法将触发,因为它们是异步的,所以你不知道哪个先结束,所以,如果 fetchStationInfo 先结束,它将有一个空值 suppliers,因为 fetchSupplier 还没有完成获取结果.

为了解决这个问题,您可以在fetchSuppliers() 之后创建一个简单的界面,当工作完成时会通知,在该工作完成后,在该界面的回调中运行fetchStationInfo(),按此顺序您在尝试在fetchStationInfo() 中获取之前,将始终拥有供应商信息。

这被称为Race Condition。

请访问这些链接以更好地了解其工作原理:

How to return dataSnapshot value as a result of a method?

android - Firebase return value from datasnapshot Why?

【讨论】:

以上是关于正在从数据库中获取数据,但仍然给出 NullPointerException的主要内容,如果未能解决你的问题,请参考以下文章

我正在尝试从我的 vuex 存储中获取数据,但它给出了一个错误

我无法从 JSON 获取数据并且没有错误

仅意图在一个活动中给出错误的意图中获取数据

想要使用外键关系获取laravel中当前登录用户的数据但给出重复的行

Quartz 调度程序无法获取 JNDI DB 资源但仍然启动

获取具有空SQL状态的错误代码4220