I have two activities and two ParseObjects respectively. In one activity I'm saving 3 strings and in another activity I'm saving Image to the ImageView. Its getting successfully saved to Parse.com but with different ObjectIds. I want the Image to be saved in other table. and then get the image based on the mobile number. I have searched the documentation referred in the Parse.com but not able to resolve this.
final ParseObject dataObject = new ParseObject("DataObject");
dataObject.put("name", name);
dataObject.put("mobilenumber", mobileNumber);
dataObject.put("occupation", occup);
dataObject.saveInBackground(new SaveCallback() {
public void done(ParseException e) {
if (e == null) {
// Success!
String objectId = dataObject.getObjectId();
} else {
// Failure!
}
}
});
Toast.makeText(getBaseContext(), "Data successfully saved "+ objectId, Toast.LENGTH_LONG).show();
This is the first activity. In the next activity I'm saving an image. I want the ObjectId but its says NULL everytime. Pls Help.
You can send the mobile number with intent to your next activity like :
public void onClick(View arg0) {
progressDialog = ProgressDialog.show(LoadImg.this, "",
"Saving Image...", true);
try {
image = readInFile(path);
}
catch(Exception e) {
e.printStackTrace();
}
ParseFile file = new ParseFile("picturePath.png", image);
file.saveInBackground();
ParseObject imgupload = new ParseObject("Image");
imgupload.put("ImageFile", file);
imgupload.put("Mobilenumber", mob);
// Create the class and the columns
and in the activity you can fetch the mobile number from the intent like :
ParseQuery<ParseObject> query = new ParseQuery<ParseObject>("Image");
mobileNumber = mbltxt.getText().toString();
query.whereEqualTo("Mobilenumber", mobileNumber);
ob = query.find();
How about this.
You can send the three strings as a bundle from the first activity to the next(second) activity using intent.putExtras(Bundle) or Intent.putExtra(String, String) and then in the second activity, get the extras and then save the strings and the image together into a ParseObject. This will also reduce the number of API requests to Parse.
Related
I want to make a diet helper app for android devices, using android studio and
I need ideas on what to use to implement the login/register system, I followed a tutorial on youtube but it was outdated and I ended up wasting my time, then I've read on google, that android studio has a library called volley that I can use with PHP and MySql to make the login system.
Do you have other ideas, or is that the best one to go with?
I'm open to suggestions so shoot!
Update:
I've created a post about how to do this using a PHP backend for your Android application. https://keithweaver.ca/posts/4/android-php-custom-login
Additionally to the link above, this is how you can setup a server.
https://github.com/kweaver00/tutorials/blob/master/setup-server.md
https://keithweaver.ca/posts/9/setup-ubuntu-server-quickly
Original Post:
This is one solution and isn't guaranteed to be the best.
You can really use anything to communicate with a server. Async Tasks or Retrofit are both popular.
Assuming you have set up a server with a LAMP stack. Make sure you have an SSL so you don't pass user information that isn't encrypted.
Create a user table in mysql
Ex.
id int default->NULL AI primary-key
user varchar 250 default->null
pass varchar 250 default->null
signupdate date default-> null
Create a log in sessions table of some sort
Ex.
id int default->NULL AI primary-key
user varchar 250 default->null
token varchar 250 default->null
addedDate date default->null
Create a log in php script (I know this probably isnt the best way to right php code)
$connection = mysqli_connect("localhost", "phpmysqluser", "password", "dbname") or die("Error 404: unable to connect");
$username = $_POST['user'];
$pass = $_POST['pass'];
//add code to remove slashes and etc.
$result = mysqli_query($connection, "SELECT * FROM userTable WHERE user='$username' AND pass='$pass'") or die("Error: this line has error");
class response{
public $loggedin =0;
public $message = "";
}
$response = new response();
if(mysqli_num_rows($result) == 1){
$logInToken = generateLogInToken();
//have a function that creates a unique token and stores it for X days or minutes
$response->loggedin = 1;
$response->message = $logInToken;
}else{
$response->message = "wrong info";
}
echo json_decode($response);
This should output a json file like this depending on your user and pass variables.
{
"loggedin" : 1,
"message" : "asdnlansdkansd"
}
Right another script that passes in the log in token and user name to check if it's valid.
$connection .... //same as above
//well it really should be a include_once cause if you change credentials
$token = $_POST['token'];
$user = $_POST['user'];
$registeredDate = "";
$today = date('Y-m-d');
$result = mysqli_query($connection, "SELECT * FROM tokenTable WHERE user='$user' AND token='$token'") or die("Error...");
class response{
public $status = 0;
}
$response = new response();
if(mysqli_num_rows($result) == 1){
//check token has been register today and if not sign them out
while($row = mysqli_fetch_array($result)){
$registeredDate = $row['addedDate'];
}
if($registeredDate == $today){
//token is valid
$response->status = 3;
}else{
//expired
$response->status = 2;
}
}else{
//user and token are not valid
$response->status = 1;
}
echo json_decode($response);
Giving a json object like:
{
"status" : 3
}
In your Android app on open, run the code to check if the account is valid if there is anything stored locally. Or just go to log in screen.
On splash screen in the onCreate (you dont need a splash screen, its actually not recommended but its the easiest way to explain the process):
if(userNameAndTokenStoredInSharedPref()){
String token = getTokenFromSharedPref();
String userName = getUserNameFromSharedPref();
checkAgainstServer(token, userName);
}else{
Intent openLogInWindow = new Intent(this, LogInActivity.class);
startActivity(openLogInWindow);
}
still in the slash activity but out of the oncreate:
protected void checkAgainstServer(String token, String user){
//using retrofit
ThisAppRestClient.get().postCheckTokenAndUser(token, user, new Callback<UserStatusCallBack>() {
#Override
public void success(UserStatusCallBack userStatusCallback, retrofit.client.Response response) {
if(userStatusCallback.getStatus() == 1){
//Invalid token
}else if(userStatusCallback.getStatus() == 2){
//Expired token
}else if(userStatusCallback.getStatus() == 3){
//Success
Intent openMainWindow = new Intent(this, MainActivity.class);
startActivity(openMainWindow);
}
}
#Override
public void failure(RetrofitError error) {
//Retrofit errors like timeouts, etc.
}
}
}
The log in activity would be something like:
logBtn.setOnClickListener(new View.onClick...
String userName = userNameEditText.getText().toString().toLowerCase().trim();
String password = passwordEditText.getText().toString().trim();
if(!TextUtils.isEmpty(userName) && !TextUtils.isEmpty(password)){
callServerLogInScript(userName, password);
}
userNameEditText.setText("");
logBtn.setVisibility(View.GONE);
}
lower down the file:
protected void callServerLogInScript(String user, String pass){
//using retrofit
ThisAppRestClient.get().postCheckTokenAndUser(user, pass, new Callback<LogInCallBack>() {
#Override
public void success(LogInCallBack logInCallback, retrofit.client.Response response) {
if(logInCallback.getLoggedIn() == 1){
//succssful
storeUserNameInSharedPref(user);
storeTokenInSharedPref(logInCallback.getMessage());
Intent openMainActivity = new Intent(this, MainActivity.class);
startActivity(openMainActivity);
}else{
//incorrect log in
logBtn.setVisibility(View.VISIBLE);
}
}
#Override
public void failure(RetrofitError error) {
//Retrofit errors like timeouts, etc.
}
}
}
The reason for not storing the user name and password directly is if the device is rooted they can manipulate the data locally but not on your server.
It depends which you want to use. If you have your own server to host, then use php,mysql. If not, you can also use other third party which provides you to add if you know php,mysql to create.
Another option is if you don't want to use php mysql to store datas, then you can proceed with parse.com
So if you want to use parse.com, just register it. It's free to use.
Hope it will match your requirement, say for eg: if you want to create registration(everything saving in datas will be handled),you need to give exact object name that matches what you given in parse.com
Even you can also create in code itself without object name. I will show you a piece of example how to create and insert for registration..
ParseUser user = new ParseUser();
user.setEmail((txtEmail));//create an edittext and get the values in strings and store..
user.setPassword(txtPassword);//same for password
user.setUsername(txtUsername);//username
user.signUpInBackground(new SignUpCallback() {
public void done(ParseException e) {
if (e == null) {
//completed..it has been registered
Toast.makeText(getApplicationContext(),
"Successfully Signed up, please log in.",
Toast.LENGTH_LONG).show();
finish();
} else {
Toast.makeText(getApplicationContext(),
"Sign up Error", Toast.LENGTH_LONG)
.show();
}
}
});
Simple one if you don't want to use php,mysql. Well documentation and easy to integrate and use it. Happy coding.
FYI: Android studio is IDE for development. And volley is HTTP library that makes networking for Android.
I need help with Parse Android API and images uploading/updating. User in my app can create event that has 1 or more images related to that event. So, this images are stored as array object that have parse files.
User can edit images that he added for that event. So, user might want to delete image or to add a new image. So, there I have problem, how I can edit array to delete specific image.
My idea was to download all images on the phone, and when user add/delete image update it locally and then upload again all images to Parse and update that array of images, but it seems that is not working properly, since I get only one image uploaded.
How I can solve this problem, any idea is appreciated.
for (int i = 0; i < ImagesSingleton.getInstance().getBytesList().size(); i++) {
String fileName = FileHelper.getFileName(getActivity(), ImagesSingleton.getInstance().getUrisList().get(i), "image");
byte[] b = ImagesSingleton.getInstance().getBytesList().get(i);
final ParseFile imgFile = new ParseFile(fileName, ImagesSingleton.getInstance().getBytesList().get(i));
imgFile.saveInBackground(new SaveCallback() {
#Override
public void done(com.parse.ParseException e) {
if (e == null) {
listOfFiles.add(imgFile);
if (listOfFiles.size() == ImagesSingleton.getInstance().getUrisList().size()) {
offer.put(ParseConstants.OFFER_PICTURES, listOfFiles);
offer.saveInBackground(new SaveCallback() {
#Override
public void done(com.parse.ParseException e) {
if (e == null) {
mProgressDialog.dismiss();
Toast.makeText(getActivity(), "Sucess saving", Toast.LENGTH_SHORT).show();
ImagesSingleton.getInstance().reset();
transferToRadar();
} else {
mProgressDialog.dismiss();
Toast.makeText(getActivity(), getResources().getString(R.string.error) + e.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
}
}
});
}
}
}
});
}
I think it is quite clear in documentation how to delete an element(s) from an Array column in Parse. You simply have to send the list of the files you want to be removed from the Array like this:
offer.removeAll(ParseConstants.OFFER_PICTURES, listOfFilesToRemove);
offer.saveInBackground();
I am attempting to get a file from Parse through a query. Parse is very vague on how to get files from the cloud, but I have managed to create a basic query to attempt to get a file
ParseQuery query = ParseUser.getQuery();
query.getInBackground(objects.get(i).getObjectId(), new GetCallback<ParseObject>() {
public void done(ParseObject object, ParseException e) {
ParseFile fileObject = (ParseFile) object.get("picture");
fileObject.getDataInBackground(new GetDataCallback() {
public void done(byte[] data, ParseException e) {
if (e == null) {
Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
ImageView image = (ImageView) findViewById(R.id.profilePicture);
image.setImageBitmap(bmp);
} else {
Toast.makeText(getApplicationContext(), "Image Not Found", Toast.LENGTH_SHORT).show();
}
}
});
}
});
The code above gives me a NullPointerException on the line:
ParseFile fileObject = (ParseFile) object.get("picture");
Need help getting the file through this method. Or is there an easier way to get a file from the Parse Cloud? All help is appreciated.
In my experience, a null pointer exception on line containing the following:
ParseFile fileObject = (ParseFile) object.get("picture");
tells me that object is null during the attempt to access the get() method. This tells me that your query is either malformed or has no matching objects on the server, more likely the second.
I don't have any information regarding the data structure of your Parse cloud, so let me give you an example instead.
If you have a regular old user, and his Parse ObjectId is xyz123ab and he has a picture file under the key/column profilePicture. You have a User containing a ParseFile containing picture data, or [User [File [PictureData]]].
Here's how you would retrieve the above in code:
String objectIdOfUser = "xyz123ab";
ParseQuery<ParseUser> query = ParseUser.getQuery();
query.getInBackground(objectIdOfUser, new GetCallback<ParseUser>() {
#Override
public void done(ParseUser parseUser, ParseException e) {
if (e == null) {
ParseFile picture = parseUser.getParseFile("profilePicture");
if (picture == null) {
// no parseFile in column "profilePicture" in this user.
return; // there will be no data to retrieve
}
picture.getDataInBackground(new GetDataCallback() {
#Override
public void done(byte[] data, ParseException e) {
if (e == null) {
if (data.length == 0) {
// data found, but nothing to extract. bad image or upload?
return; // failing out
}
// SUCCESS
// convert data and display in an imageview
} else {
// ParseFile contained no data. data not added to ParseFile?
}
}
});
} else {
// no users had this objectId
}
}
});
Change ParseUser to ParseObject in the following if you aren't using a ParseUser. Don't forget to change the string "ObjectName" to your object.
// ... etc
ParseQuery<ParseObject> query = ParseObject.getQuery("ObjectName");
query.getInBackground(objectIdOfObject, new GetCallback<ParseObject>() {
#Override
public void done(ParseObject object, ParseException e) {
if (e == null) {
ParseFile picture = object.getParseFile("profilePicture");
// etc...
Also, be certain that your data is loaded into the server properly. This can be tricky to determine on the web-client for Parse, unfortunately. Uploading an image properly is similar to this but in reverse, and an answer for another day.
Please review your code to get an objectId as shown here:
objects.get(i).getObjectId()
to determine if you are indeed accessing the objectId you thought you were, perhaps with a log or toast or debug breakpoint. That could be were everything starts to break down.
Your code looks fine, you simply need to check if the current row has a file reference in it's picture column. If the column is empty then you will obviously get a null reference when reading it out as a ParseFile.
Generate dynamically column with file data type in parse.com using android code
ParseObject tableName = new ParseObject("NewTable");
tableName.put("columnOne", "string"); // string
tableName.put("columnTwo", 12); // integer
tableName.put("Filedata", ); <----------Here must be file data type
tableName.saveInBackground();
To store with file data type ---
Get the data in byte[] form and then create a ParseFile with it.
In this example, we'll just use a string:
byte[] data = "Working at Parse is great!".getBytes();
ParseFile file = new ParseFile("filedata.txt", data);
file.saveInBackground();
Finally, after the save completes, you can associate a ParseFile onto a ParseObject just like any other piece of data:
ParseObject tableName = new ParseObject("NewTable");
tableName.put("columnOne", "string"); // string
tableName.put("columnTwo", 12); // integer
tableName.saveInBackground();
tableName.put("Filedata", file);
tableName.saveInBackground();
Retrieving it back involves calling one of the getData variants on the ParseObject. Here we retrieve the Filedata file off another object:
ParseFile applicantFile = (ParseFile)anotherApplication.get("Filedata");
applicantFile.getDataInBackground(new GetDataCallback() {
public void done(byte[] data, ParseException e) {
if (e == null) {
// data has the bytes for the resume
} else {
// something went wrong
}
}
});
This is explained more thoroughly at Android Parse Guide.
I want to use the parse database for developing web app, since data will upload from the desktop PC and retreival of the same will be done in parse mobile application.
Is it possible to use the parse database for website backend ?
Since I want to use same parse database for application and desktop version.
Can anyone please help me, by providing some idea how to achieve that?
Thanks in advance.
Is it possible to use the parse database for website backend ?
YES, it is possible: .NET Guide, REST API
Since I want to use same parse database for application and desktop version.
YES, you can use same database for application and desktop version.
for store data using ANDROID create object like:
ParseObject gameScore = new ParseObject("GameScore");
gameScore.put("score", 1337);
gameScore.put("playerName", "Sean Plott");
gameScore.put("cheatMode", false);
gameScore.saveInBackground();
above code is create table in parse.com(database is automatically created when you store data using object.) check dashboard: like below image
for fetch data try this way:
ParseQuery query = new ParseQuery("GameScore");
query.getInBackground("xWMyZ4YEGZ", new GetCallback() {
public void done(ParseObject object, ParseException e) {
if (e == null) {
// object will be your game score
} else {
// something went wrong
}
}
});
same way you can use for WEB Application as well Desktop application (REST API)
for create table User i have to create object like:
ParseObject gameScore = new ParseObject("User");
gameScore.put("First Name", "dhaval");
gameScore.put("Last Name", "Sodha");
gameScore.put("Email", "xyz#gmail.com");
gameScore.put("Phone", "9876543210");
gameScore.put("Address", "xyz");
gameScore.put("City", "ahmedabad");
gameScore.put("Country", "India");
gameScore.saveInBackground();
above Object ll create table with fields(ID ,First Name, Last Name, Email, Phone, Address, City, ... time, created...etc )
EDITED:
get data like (SELECT * FROM USER WHERE CITY = 'AHMEDABAD' and COUNTRY = 'INDIA')
ParseQuery lotsOfWins = new ParseQuery("User");
lotsOfWins.whereEqualTo("city", "Ahmedabad");
ParseQuery fewWins = new ParseQuery("User");
fewWins.whereEqualTo("country", "India");
List<ParseQuery> queries = new ArrayList<ParseQuery>();
queries.add(lotsOfWins);
queries.add(fewWins);
ParseQuery mainQuery = ParseQuery.or(queries);
mainQuery.findInBackground(new FindCallback() {
public void done(List<ParseObject> scoreList, ParseException e) {
if (e == null) {
Log.d("score", "Retrieved " + scoreList.size() + " scores");
// HERE SIZE is 0 then 'No Data Found!'
} else {
Log.d("score", "Error: " + e.getMessage());
}
}
Here: public void done(List<ParseObject> scoreList, ParseException e) you get result in object
List<ParseObject>: is list of object return by query.
ParseException: is Exception if occur..
So, scoreList.size() give you Total size of all Object return by Query.
How Fetch data:
String username = scoreList.getString("username");
How Save File: (Whatever MIME type like png,jpg,doc,txt....etc)its works for all
Upload File using Below code:
ByteArrayOutputStream stream = new ByteArrayOutputStream();
USERIMAGE.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
String UsetPhoto = "user"+System.currentTimeMillis()+"image";
ParseFile file = new ParseFile(UsetPhoto, byteArray);
ParseObject gameScore = new ParseObject("UserDetails");
gameScore.put("userName", "" + userName.getText().toString());
gameScore.put("userPhoto", "" + file);
gameScore.saveInBackground();
retrive file from parse API using above object:
ParseFile applicantResume = (ParseFile)gameScore.get("userPhoto");
applicantResume.getDataInBackground(new GetDataCallback() {
public void done(byte[] data, ParseException e) {
if (e == null) {
// data has the bytes for the resume
} else {
// something went wrong
}
}
});
Here you get: public void done(byte[] data, ParseException e)
byte[] : byte[] of file(whatever file type - if you have uploaded png then save that byte as png).
ParseException : is Exception if occur..