从firebase访问数据并将其设置为变量时,应用程序崩溃

时间:2018-03-11 14:42:59

标签: android firebase firebase-realtime-database

在这里考虑以下代码我从firebase数据库访问数据并更新变量id。但是当我尝试运行应用程序时,崩溃显示我在下面附加的消息。

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleMap.OnMapLongClickListener {

private GoogleMap mMap;

LocationManager locationManager;

LocationListener locationListener;
private FirebaseAuth mAuth;
DatabaseReference mData;
DatabaseReference mId;
static int id = 1;


@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {

            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);

            Location lastKnownLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);

            centerMapOnLocation(lastKnownLocation, "Your location");

        }


    }

}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_maps);
    // Obtain the SupportMapFragment and get notified when the map is ready to be used.
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
    mAuth = FirebaseAuth.getInstance();
    final String uid = mAuth.getUid();
    mData = FirebaseDatabase.getInstance().getReference().child("Users").child(uid).child(String.valueOf(id));
    mId = FirebaseDatabase.getInstance().getReference().child("Users");
    mId.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            updateid(dataSnapshot,uid);
           // id = Integer.parseInt(dataSnapshot.child("id").getValue(String.class));
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
}
LatLng userLocation;
public void centerMapOnLocation(Location location, String title) {
    if(location!= null){
        double latitude = location.getLatitude();
        double longitude = location.getLongitude();
       userLocation = new LatLng(latitude, longitude);
    }



    mMap.clear();

    if (title != "Your location") {

        mMap.addMarker(new MarkerOptions().position(userLocation).title(title));

    }

    mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(userLocation, 10));

}

@Override
public void onMapLongClick(LatLng latLng) {

    Geocoder geocoder = new Geocoder(getApplicationContext(), Locale.getDefault());
    String address="";

    try {
        List<Address> addresses = geocoder.getFromLocation(latLng.latitude,latLng.longitude,1);



        if (addresses != null &&addresses.size() != 0)
        {
            if(addresses.get(0).getSubThoroughfare() != null)
            {
                if(addresses.get(0).getThoroughfare()!=null)
                {
                    address+=addresses.get(0).getSubThoroughfare();

                }

                address+=addresses.get(0).getThoroughfare();
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    if(address == "")
    {
        SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZZZZZ",Locale.ENGLISH);
        address=dateFormat.format(new Date());
    }

    mMap.addMarker(new MarkerOptions().position(latLng).title(address));


   // DatabaseReference ref = mData.child(mAuth.getUid());
    mData.child("lat").setValue(latLng.latitude);
    mData.child("long").setValue(latLng.longitude);

    id++;
    mId.child("Id").setValue(id);



    Toast.makeText(getApplicationContext(),"Saved",Toast.LENGTH_SHORT).show();

}

private void updateid(DataSnapshot data,String uid) {
  // data.child(uid).getValue(User.class).getName();

    User u = new User();
    for(DataSnapshot ds : data.getChildren()) {

        u.setId(ds.child(uid).getValue(User.class).getId());

    }
    id = u.getId(); 

}

/**
 * Manipulates the map once available.
 * This callback is triggered when the map is ready to be used.
 * This is where we can add markers or lines, add listeners or move the camera. In this case,
 * we just add a marker near Sydney, Australia.
 * If Google Play services is not installed on the device, the user will be prompted to install
 * it inside the SupportMapFragment. This method will only be triggered once the user has
 * installed Google Play services and returned to the app.
 */
@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;

    mMap.setOnMapLongClickListener(this);

    locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);

    locationListener = new LocationListener() {
        @Override
        public void onLocationChanged(Location location) {

            if(location!= null){
                double latitude = location.getLatitude();
                double longitude = location.getLongitude();
              //  userLocation = new LatLng(latitude, longitude);
                centerMapOnLocation(location, "Your location");
            }



        }

        @Override
        public void onStatusChanged(String s, int i, Bundle bundle) {

        }

        @Override
        public void onProviderEnabled(String s) {

        }

        @Override
        public void onProviderDisabled(String s) {

        }
    };
    if (Build.VERSION.SDK_INT < 23) {

        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);

    } else {

        if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {

            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);

            Location lastKnownLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);

            centerMapOnLocation(lastKnownLocation, "Your location");

        } else {

            ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, 1);

        }


    }
}

我的User课程如下

public class User {
private String name;
private String phone;
private  String email;
private  String password;
int id;


public User() {

}


public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}


public String getPhone() {
    return phone;
}

public void setPhone(String phone) {
    this.phone = phone;
}

public String getEmail() {
    return email;
}

public void setEmail(String email) {
    this.email = email;
}

public String getPassword() {
    return password;
}

public void setPassword(String password) {
    this.password = password;
}

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

}

错误日志消息以

命名
Process: com.example.ashwanths.helpwithfood, PID: 32645
java.lang.NullPointerException: Attempt to invoke virtual method 'int com.example.ashwanths.helpwithfood.User.getId()' on a null object reference
    at com.example.ashwanths.helpwithfood.MapsActivity.updateid(MapsActivity.java:174)
    at com.example.ashwanths.helpwithfood.MapsActivity.access$000(MapsActivity.java:38)
    at com.example.ashwanths.helpwithfood.MapsActivity$1.onDataChange(MapsActivity.java:87)
    at com.google.android.gms.internal.zzegf.zza(Unknown Source)
    at com.google.android.gms.internal.zzeia.zzbyc(Unknown Source)
    at com.google.android.gms.internal.zzeig.run(Unknown Source)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:148)
    at android.app.ActivityThread.main(ActivityThread.java:5417)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

我想要的输出是,如果我在地图中添加一个标记,那么firebase数据库中的Id值应该自动递增

Screen shot of my database

2 个答案:

答案 0 :(得分:1)

问题是这个。您的数据库引用将在您的数据库中获得一个用户:

mData = FirebaseDatabase.getInstance().getReference().child("Users").child(uid)

但是,当您通过用户的属性调用updateid()方法时,

private void updateid(DataSnapshot data,String uid) {
  // data.child(uid).getValue(User.class).getName();

    User u = new User();
    for(DataSnapshot ds : data.getChildren()) {

        u.setId(ds.child(uid).getValue(User.class).getId());

    }
    id = u.getId(); 

}

这例如ds.child(uid)无法正常工作,然后您尝试将其转换为用户,这是此数据快照不可用的内容。当firebase执行getValue(User.class)时,它将返回null,这就是您在这里获得NPE的原因。

变量data已经有一个用户(作为数据快照)。所以你应该这样做:

private void updateid(DataSnapshot data,String uid) {
   data.getRef().child("id").setValueAsyn(newID);

}

编辑:

如果您想获取用户对象,请按以下步骤操作:

private void updateid(DataSnapshot data,String uid) {
      Integer retrievedID = data.getValue(Integer.class);
      if(retrievedID!=null){
       id = retrievedID;
       }

    }

答案 1 :(得分:1)

您收到以下错误:

java.lang.NullPointerException: Attempt to invoke virtual method 'int com.example.ashwanths.helpwithfood.User.getId()' on a null object reference

因为您在名为getId()的引用上调用null方法。

正如我在您的数据库中看到的,以下代码行:

ds.child(uid).getValue(User.class);

已经返回User类对象。无需创建另一个User类对象。如果这样做,该对象内的所有字段也将具有值null

字段Id: 2不应放在Users节点下方。此节点下的所有子节点应该属于同一类型,类型为User类,而不是类型IntegerLong。要解决此问题,请将该字段移动到yopur数据库的另一个位置。

如果{i}用户可以修改id,我还建议您使用Firebase Transactios在数据库中获得准确的数据。