在这里考虑以下代码我从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值应该自动递增
答案 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
类,而不是类型Integer
或Long
。要解决此问题,请将该字段移动到yopur数据库的另一个位置。
如果{i}用户可以修改id
,我还建议您使用Firebase Transactios在数据库中获得准确的数据。