I've been trying to use the Parse library to access MongoDB in order to create users or objects for my Android application. The issue is that every time I attempt to SignUpInBackground or SignInInBackground I get this super unspecific error.
"java.lang.NullPointerException: value == null"
Just value == null.. I have no idea which value this refers to but the most frustrating part is that the code I'm using works perfectly in one app and despite copying it over, it always returns this error.
I usually wouldn't bother making a question for my issue but I've been trying to find a solution to this for about a week now and have been unable to find anything related to my issue online.
Hope someone out there has seen this before, as I'm about out of ideas for this one. Thanks in advance to anyone who gets back to me on this :)
The Sign Up Method:
private void signUp(){
String username = "Andy"; //Temp
ParseUser user = new ParseUser();
user.setUsername(username);
user.setEmail(txtUsername.getText().toString());
user.setPassword(txtPassword.getText().toString());
Log.i(TAG,"SignUp method. Parse user = " + user.getUsername() + ", " + user.getEmail());
user.signUpInBackground(new SignUpCallback() {
#Override
public void done(ParseException e) {
if(e==null){
Log.i(TAG, "Successfully created new user!");
signIn();
} else {
Log.i(TAG, "Failed to create new user. Error: " + e.getMessage());
Toast.makeText(getContext(),"Sign up failed! " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
}
Error:
I/LogIn: Validation success
I/LogIn: SignUp method. Parse user = Andy, test
I/LogIn: Failed to create new user. Error: java.lang.NullPointerException: value == null
Edit:
While stepping through the parse libraries, I ended up with this error message several times in the log.
I/art: Rejecting re-init on previously-failed class java.lang.Class
Related
I am grabbing the android device token and saving it to firestore. This works in most of the cases totally fine. Now I encountered a device where it does not work. Oddly enough I end up with attributes in firestore that my model does not reflect and I do not understand where those attributes and their values come from.
This is my method to retrieve the token:
public static void updateToken(String userId, FcmToken.Action action) {
if (StringUtils.checkNull(userId)) return;
//FCM
FirebaseMessaging.getInstance().getToken().addOnCompleteListener(task -> {
if (!task.isSuccessful()) {
Log.w(TAG, "Could not get firebase token. ", task.getException());
return;
}
String token = task.getResult();
Log.i(TAG, "[FCM TOKEN]: " + token);
//Do not ask firebase to write an existing token again,
//this only creates traffic and costs but does not change the database
String storedToken = FcmProvider.loadToken(false);
if (StringUtils.checkNull(storedToken) || !token.equals(storedToken) || action == FcmToken.Action.DELETE) {
FcmToken fcmToken = new FcmToken(token, userId, action);
FcmRepo.getInstance().setToken(fcmToken, documentId -> {
Log.d(TAG, "Token " + action + " successfully");
FcmProvider.saveToken(token);
}, e -> {
Log.d(TAG, "Failed to " + action + " token. " + e);
});
} else {
Log.d(TAG, "Stored token is identical. No update needed");
}
});
}
This is the FcmToken class (And I assume the way I use the field values here are the issue, yet I do not understand the outcome)
#Getter
#Setter
#IgnoreExtraProperties
public class FcmToken {
private String userId;
private FieldValue fcmToken;
#ServerTimestamp
private Date ut;
public enum Action {SET, DELETE}
public FcmToken(String fcmToken, String userId, Action action) {
this.userId = userId;
if (action == Action.SET) this.fcmToken = FieldValue.arrayUnion(fcmToken);
else if (action == Action.DELETE) this.fcmToken = FieldValue.arrayRemove(fcmToken);
}
}
For completness this is the method I use to set the token:
public void setToken(#NonNull FcmToken fcmToken, #Nullable OnSetSuccessListener callbackSuccess, #Nullable OnFailureListener callbackFailure) {
getFcmRef().document(fcmToken.getUserId()).set(fcmToken, SetOptions.merge()).addOnCompleteListener(task ->...);
}
Now this is what ends up in my firestore for that user only:
This HAS to to come from the app itself. There is no other way this document could have been created:
If I use another device or the emulator the result looks like expected. Where does the "a" field come from? Why is it assigned to userId and why is there no fcmToken field?
The problem is, that I do not have physical access to the phone that produces this behaviour (Samsung S21 Ultra, Android 12). I need to debug this without having access to the log outputs.
But I know that the task comes back successfully (I used another version to save the error in the token field and there was none).
Any ideas?
This typically means that you didn't configure ProGuard correctly, and it's minifying the classes that you're writing to the database.
You'll need to prevent ProGuard from modifying the classes that you use to interact with the database. See the Firebase documentation on configuring ProGuard (the link is for the Realtime Database, but the same applies to Firestore), or one of these previous questions about configuring ProGuard for Firebase.
I know that this may seem to be a rather broad question, but I have been unable to figure out how to create a Person in a Person Group using the Microsoft Face API in Android Studio.
I have tried the following code to make a CreatePersonResult object in Android:
try {
CreatePersonResult person1 = faceServiceClient.createPerson(personGroupId, "Bob", "My Friends");
Toast.makeText(getApplicationContext(), "Created Person called Bob", Toast.LENGTH_LONG).show();
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "Creation failed: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
The above code outputs: "Creation failed: null" which means that the Exception was null for some reason.
In Visual Studio, to create a Person I simply have to do the following:
CreatePersonResult person1 = await faceServiceClient.CreatePersonAsync(personGroupId, "Bob");
Does anyone know how I can create the Person in a Person Group in Android? I have been unable to figure out how to do this in Android, but found plenty of tutorials for Visual Studio.
I'm trying to save a GeoPolygon into my Parse server using an android app but I keep getting an:
error 111: this is not a valid polygon
this is my code:
//create the parse object
ParseObject obj = new ParseObject("SomeClass");
List<ParseGeoPoint> geoPoints = new ArrayList<ParseGeoPoint>();
geoPoints.add(new ParseGeoPoint(1.468074, 110.429638));
geoPoints.add(new ParseGeoPoint(1.468075, 110.429287));
geoPoints.add(new ParseGeoPoint(1.467376, 110.429681));
geoPoints.add(new ParseGeoPoint(1.467373, 110.429283));
ParsePolygon geoPolygon = new ParsePolygon(geoPoints);
obj.put("Boundaries", geoPolygon);
obj.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
Toast.makeText(getContext(), "Geo Polygon save complete.", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getContext(), "Geo Polygon save failed. error: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
I followed the Docs for geopolygons here:
http://docs.parseplatform.org/android/guide/#parsepolygon
and somehow, even when I copy pasted the code provided in the docs, it doesnt work.
Any suggestions/ solutions are most welcomed.
I believe not many people may see this but I'll post my solution to this anyway.
The issue was solved after I updated the version of my Parse Server. I didn't note which version I updated the Parse Server from but my current Parse Server is now v2.7.1 .
Previous/ older version of Parse Server does not support geo-Polygons.
Why does parse not appear to be doing anything with my query whatsoever. It's almost as if the entire block is ignored..
try {
Log.w("UpdateContacts", "Attempting an update");
List<ParseObject> result = friendshipAndUserQuery.find();
for (ParseObject friendship : result) {
Log.i("UpdateContacts", "Found friendship" + friendship.getObjectId());
UserObject friend = (UserObject) friendship.getParseObject("to");
Log.i("UpdateContacts", "Converted friendship to friend " + friend.getObjectId());
contacts.add(friend);
((MainActivity) mContext).notify("UpdateContacts", friend.getObjectId() + " / " + friend.getUsername(), true);
}
} catch (ParseException e) {
Log.e("ParseException", e.toString());
((MainActivity) mContext).notify("UpdateContacts", e.toString(), true);
}
I get the "attempting an update" Log, but nothing else. I can see from my Parse portal that the query has run, my android simply gets nothing back at all.. not an empty set, nothing. No logs were made..
Solved
Query referenced the incorrect table name (case sensitive) and Parse simply stops all related code, rather than spouting out an error..
I am trying to retrieve a new column called "address" I created in Parse User in my android app. But it returns me nullPointerException error and returns me nothing although I filled the address in the table.
This link only shows the way to store your custom field in the user table but I need to retrieve what I stored there.
This is my code:
ParseUser pUser = ParseUser.getCurrentUser();
userAddress.setText(pUser.getString("address").toString());
I tried get("address") as well but still it returns me nothing. Is there something I'm missing here?
Alright, I found the answer on my own. It turns out that Parse caches the ParseUser.getCurrentUser() object locally and the reason I wasn't able to get the data from server was because I changed the data on server and the client cache wasn't updated.
I was able to fix this by fetching the ParseUser object from the server:
ParseUser.getCurrentUser().fetchInBackground();
and then after the object is retrieved from the server I was able to get the address field on my client.
You need to call it using a Query, then display it in a textView/editText. Try the following:
final ParseQuery<ParseObject> address = ParseQuery.getQuery("//Class Name");
address.getFirstInBackground(new GetCallback<ParseObject>() {
public void done(ParseObject reqAdd, ParseException e) {
if (address != null) {
Log.d("quizOne", "Got it");
//Retrieve Age
String //CreateNewString = reqAdd.getString("//Column name");
TextView //textView Name = (TextView) findViewById(R.id.//textView ID);
//textViewName.setText(//StringName);
Toast.makeText(getApplicationContext(),
"Successfully Recieved Address",
Toast.LENGTH_LONG).show();
} else {
Log.d("//EnterName", "//Enter Error Message");
Toast.makeText(getApplicationContext(),
"Can't receive address", Toast.LENGTH_LONG)
.show();
}
}
});
Short answer: that user probably just doesn't have an address set.
Long answer: your code snippet will throw exceptions often, and you should expect and handle those, or use tests to avoid throwing them.
Read this page: http://en.wikibooks.org/wiki/Java_Programming/Preventing_NullPointerException
Key example/excerpt:
Object obj = null;
obj.toString(); // This statement will throw a NullPointerExcept
So pUser.getString("address") appears correct. But calling .toString() on the result requires you to be try/catching the exception. Maybe do
ParseUser pUser = ParseUser.getCurrentUser();
if (pUser.getString("address") != null) {
userAddress.setText(pUser.getString("address"));
}
BTW, I believe the error is "nullPointerException" fyi! :)