Waiting for device token with parse Android - android

I am currently developing on Android and using Parse. My goal is to get the device Token and send it to a web service in order to register an install.
I have this code :
installation.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
// Saved!
if(e==null){
String deviceToken = (String)installation.get("deviceToken");
String objectId = installation.getObjectId();
Log.d("test","device token : "+deviceToken);
Log.d("test","object id : "+objectId);
}else{
Log.d("test","error : "+e.getMessage());
}
}
});
ObjectId is fine but I am always getting null for the deviceToken. But on my Parse.com back-end the DeviceToken is here and well defined...
So, what is the solution to avoid getting null and to send the right data ?
I found nothing about my problem in the parse documentation or Parse Android community.
Thank you very much for your answers.

I think you should use following method to get current installation. and then device Id - In above code, the save call back is not returning you the saved object
String deviceToken = ParseInstallation.getCurrentInstallation().get("deviceToken");
String objectID = ParseInstallation.getCurrentInstallation().getObjectId();
Hope it helps!

You can get installationID and work with it:
ParseInstallation installation = ParseInstallation.getCurrentInstallation();
String installationID = installation.getInstallationId();
because sometimes deviceToken is null

Related

Parse deviceToken not in format

I don't know why deviceToken in Parse isn't like GCM token which I get from my device.
In my device, i got GCM token like APA91.... but when it stored to Parse my deviceToken become absurd format like this
http://i.stack.imgur.com/ONLfa.png
What's going on with Parse? There is any wrong configuration?
To get the deviceToken in parse, just use following code:
ParseInstallation.getCurrentInstallation().saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
String deviceToken = (String) ParseInstallation.getCurrentInstallation().get("deviceToken");
}
});
I was able to get the correct type with it of version 1.7.1. I don't know the newest version.

How to retrieve authData from a ParseUser?

I'm trying to retrieve the authData field from a ParseUser. With Parse 1.9.1, I used to do it like so:
ParseUser user = ParseUser.getCurrentUser();
HashMap authDataMap = (HashMap)user.get("authData");
HashMap facebookMap = (HashMap)authDataMap.get("facebook");
String facebookId = (String)facebookMap.get("id");
And this worked fine.
Something changed though. I don't know if it's because I updated to Parse 1.9.2 or if something changed on the Parse server side, but authData is no longer accessible. The line user.get("authData") returns null. Even if I re-fetch the user.
Ultimately I want to retrieve the Facebook id from the ParseUser, preferably without reaching out to Facebook. Is this no longer possible?
If you are using ParseFacebookUtils to perform login Facebook user then after successfully login from in parse try to get GraphUser using following to fetch Facebook user data-
Request.newMeRequest(ParseFacebookUtils.getSession(),
new Request.GraphUserCallback() {
#Override
public void onCompleted(
final GraphUser fbUser,
Response response) {
try {
if (fbUser != null
&& parseUser != null
&& fbUser.getName()
.length() > 0) {
// Facebook user data
String fbId = fbUser.getId();
} else {
// Facebook user not logged in
}
} catch (Exception e) {
e.printStackTrace();
stopLoading();
}
}
}).executeAsync();
Have you taken a look at Facebook Users section in the Parse.com documentation. I think authData is for internal communication, not meant to be called (any more).

Accessing a custom column in Parse.com user table returning me null

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! :)

com.parse.ParseException: Clients aren't allowed to perform the find operation on the installation collection

I am new to parse ,i am able to store data to its database but whenever i try to retrieve some information like object-id from database i usually get the above mentioned error.Query which i am using to retrieve the object-id corresponding to the given Friend-id.
ParseQuery<ParseObject> query = ParseQuery.getQuery("_Installation");
query.whereEqualTo("FriendId", FrndTextString);
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> results, ParseException e) {
if (e == null) {
for (ParseObject x : results) {
String Objectid = x.getString("objectId");
objectidEditText.setText(Objectid);
}
} else {
Toast.makeText(getApplicationContext(),
"Error in retreving Data", Toast.LENGTH_LONG)
.show();
}
}
});
Please help me in solving this issue as I googled a lot but haven’t found anything good solution.Any help will be appreciated.
Thanks.
The _Installation class is an internal class from Parse. The exception occurs because you are trying to access data that is protected by a specific user with specifc ParseACL .
Documentation from Parse:
Every Parse application installed on a device registered for push notifications has an associated Installation object. The Installation object is where you store all the data needed to target push notifications. For example, in a baseball app, you could store the teams a user is interested in to send updates about their performance. Saving the Installation object is also required for tracking push-related app open events.
In Android, Installation objects are available through the ParseInstallation class, a subclass of ParseObject. It uses the same API for storing and retrieving data. To access the current Installation object from your Android app, use the ParseInstallation.getCurrentInstallation() method. The first time you save a ParseInstallation, Parse will add it to your Installation class and it will be available for targeting push notifications.
Try to use another Class, like "Ranking". Ex:
ParseQuery<ParseObject> query = ParseQuery.getQuery("Ranking");
query.whereEqualTo("FriendId", FrndTextString);
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> results, ParseException e) {
if (e == null) {
for (ParseObject x : results) {
String Objectid = x.getString("objectId");
objectidEditText.setText(Objectid);
}
} else {
Toast.makeText(getApplicationContext(),
"Error in retreving Data", Toast.LENGTH_LONG)
.show();
}
}
});
You have to pay attention to setup ParseACL correctly for each user and Class, if you want to find public information of others users. At least, all user have to be "Public Read" for data that you want.
Before saving any data in Parse, you have to setup the environment with this tutorial. After, you have to Create the ParseUser and login with it. Parse has an automatic way to create an user, just calling:
ParseUser.enableAutomaticUser();
ParseUser.getCurrentUser().increment("RunCount");
ParseUser.getCurrentUser().saveInBackground();
To save any data in Parse, you can use:
ParseObject gameScore = new ParseObject("GameScore");
gameScore.put("score", 1337);
gameScore.put("playerName", "Sean Plott");
gameScore.put("cheatMode", false);
gameScore.saveInBackground();
Parse Server will automatically create the new class "GameScore", if is not exist. And will create all column, like "score", "playerNAme" and "cheatMode" if it not exist.
To go through with Parse, please read API Doc, it is so helpful.
The Installation class can't be queried like that. Use ParseInstallation.getCurrentInstallation(); instead.
for example,
ParseInstallation.getCurrentInstallation().getString("FriendId");

Register device id directly with Amazon SNS

I am using the Amazon Web Service to send push notifications directly to a device. After I install the app I get the device id, that I need to manually add to the Amazon SNS. I would like to know if there is anyway to register the device id directly with the amazon server the moment the user starts the application.
I have read this, but found it difficult to understand. Does anyone have any previous experience of how to do this?
EDIT 2 (What I have done so far)
I've followed the instructions from this link
I download the snspobilepush.zip file as instructed and extract and import the project into eclipse. I add the GCM project number, add the jar files and run the application. I get my device registration Id.
I open the Amazon SNS, add my device id and I publish a message. I receive the message on my mobile phone. Works great so far.
MY PROBLEM
I would be having a lot of potential users for my application. So adding every device id manually to the SNS makes no sense. I need the Amazon SNS to directly register my device id when I start the app. Is there any option for me to do that? I couldn't find any definitive answer in the docs.
This link tells me to Use the "AWS Token Vending Service". However, I could not find any example of how to do that.
Using the AmazonSNSClient documented here:
http://docs.aws.amazon.com/AWSAndroidSDK/latest/javadoc/
it should be possible to register using code similar to this:
AWSCredentials awsCredentials = new BasicAWSCredentials("XXXXXX", "XXXXXXXXXXXXXXX");
String platformApplicationArn = "arn:aws:sns:us-east-1:123456789:app/GCM/myappname";
AmazonSNSClient pushClient = new AmazonSNSClient(awsCredentials);
String customPushData = "my custom data";
CreatePlatformEndpointRequest platformEndpointRequest = new CreatePlatformEndpointRequest();
platformEndpointRequest.setCustomUserData(customPushData);
platformEndpointRequest.setToken(pushNotificationRegId);
platformEndpointRequest.setPlatformApplicationArn(platformApplicationArn);
CreatePlatformEndpointResult result = pushClient.createPlatformEndpoint(platformEndpointRequest);
Log.w(TAG, "Amazon Push reg result: " + result);
It was not liking my ARN, but that was a stupid typo that Reid pointed out and is now fixed above.
There is Android AWS SDK available to use. Check out the documentation link: http://docs.aws.amazon.com/AWSAndroidSDK/latest/javadoc/
Also, more information available: http://aws.amazon.com/sdkforandroid/
This is working for Firebase and Cognito. An AsyncTask is necessary to avoid running on the Main Thread.
private class RegisterIdForAWS extends AsyncTask<String, Void, Void> {
private Exception exception;
protected Void doInBackground(String... urls) {
try {
String pushNotificationRegId = FirebaseInstanceId.getInstance().getToken();
if (pushNotificationRegId != null) {
CognitoCachingCredentialsProvider provider = new CognitoCachingCredentialsProvider(
getApplicationContext(),
"us-west-2:aaaaaaaaa-1234-1234-1234-0bbbbbbbbbbbb",
Regions.US_WEST_2);
String platformApplicationArn = "arn:aws:sns:us-west-2:123456789:app/GCM/appname";
AmazonSNSClient pushClient = new AmazonSNSClient(provider);
pushClient.setRegion(Region.getRegion(Regions.US_WEST_2));
String customPushData = "";
CreatePlatformEndpointRequest platformEndpointRequest = new CreatePlatformEndpointRequest();
platformEndpointRequest.setCustomUserData(customPushData);
platformEndpointRequest.setToken(pushNotificationRegId);
platformEndpointRequest.setPlatformApplicationArn(platformApplicationArn);
CreatePlatformEndpointResult result = pushClient.createPlatformEndpoint(platformEndpointRequest);
Log.w(TAG, "Amazon Push reg result: " + result);
}
} catch (Exception e) {
this.exception = e;
}
return null;
}
protected void onPostExecute(String text) {
Log.w(TAG, "Amazon Push reg Finished");
}
}

Categories

Resources