Parse.com pointer data for updating tables using Android - android

I am making an application for saving user information. I have successfully updated my manual table "UserInfo". Now I want to get the data from that table by using Current User Phenomena. My code snippet is given below:
final ParseUser user = ParseUser.getCurrentUser();
user.put("firstName", fName.getText().toString());
user.put("lastName", lName.getText().toString());
user.put("email", mailText.getText().toString());
// Here I am updating data in UserInfo Table, I want to get
// values from this table now, I mean I want to retrieve data here.
final ParseObject update = new ParseObject("UserInfo");
update.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException arg0) {
update.put("doctor", doInfo.getText().toString());
update.put("medi", medtion.getText().toString());
update.put("icalNote", medNotes.getText().toString());
update.put("meCondition", medCond.getText().toString());
update.put("agies", agiesReact.getText().toString());
update.saveInBackground();
}
});

in your UserInfo class you add new field 'ptrUser' that is type pointer and that has value = getCurrentUser().
When you have saved the UserInfo with the ptr field, you can do a flat query retreiving both of the classes
in REST API idiom :
GET ./classes/UserInfo/null?include=ptrUser
SDK idiom:
query.include($ptrUser)

Related

FirebaseIndexRecyclerAdapter - How to get the value of each key from the key reference location?

I have the following denormalized data structure:
A Contact can associate with multiple Records. A Record can have multiple associated Contacts (many<->many relationship). To keep track of their relationship, an int value to indicates the contact's role in a particular record, and store the role value in two separate references
Contact
- Contact1:data
- Contact2:data
- Contact3:data
Record
- Record1:data
- Record2:data
Record_Role_Ref
- Record1
-- Contact1: roleA
-- Contact2: roleA
-- Contact3: roleD
- Record2
-- Contact1: roleB
Contact_Role_Ref
- Contact1
-- Record1: roleA
-- Record2: roleB
I'm using FirebaseIndexRecyclerAdapter is to show a list of associated Contacts to a particular Record id. So for the key reference I would use Record_Role_Ref/record_id, and for the data reference I would use Contact, like so:
// Setup the reference to the all the associated contact list in record_role_ref, using the record id as key
Query mRecordRoleRef = firebaseDatabase.getReference().child(DB_RECORD_ROLE_REF).child(mRecordId);
// Reference the Contact data ref
Query mContactRef = firebaseDatabase.getReference().child(DB_CONTACT);
FirebaseIndexRecyclerAdapter mContactAdapter = new FirebaseIndexRecyclerAdapter<Contact, ContactViewHolder>(Contact.class,
R.layout.item_contact,
ContactViewHolder.class,
mRecordRoleRef, // The Firebase database location containing the keys associated contacts to this record
mContactRef)// The Firebase database location to watch for data changes. Each key key found at keyRef's location represents a list item in the RecyclerView.
Limitation(s): I don't want to store the role value in each contact and record object because each time a role is changed, both the contact and record's entire object would have fetched and updated. Users want to delete, modify, move both contact and records, and change roles.
Problem(s):
The contact's role value is stored as value of the key in the mRecordRoleRef. Is it possible/how to get the value from the key reference in on-go with FirebaseIndexRecyclerAdapter? What is the good/best practice in this kind of situation?
Thanks In Advance :)
As of now, I just form another data read request inside the populateViewHolder callback method. Since the data read request is itself also async, I'm not yet sure if this would work for a large list and when the view recycles. The viewHolder returned by the populateViewHolder is set to final.
Query mRecordContactRoleRef = firebaseDatabase.getReference().child(DB_RECORD_CONTACT_ROLE_REF).child(mRecordId).child(mContact.getContactId());
mRecordContactRoleRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Getting the role int base on record type
Long roleNum = (Long) dataSnapshot.getValue();
viewHolder.setContactRoleTv("hi, the role is " + roleNum);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});

Android parse.com setObjectId

How set objectId with Parse.com with primary key.Can you help me ?
When i create new row, i want setObjectId of row.
final ParseObject parseObject = new ParseObject(ChapsModel.PARSE_OBJECT);
parseObject.put(ChapsModel.PARSE_FIELD_NAME_CHAPS,
chapsModel.get(i)
.getNamChap());
parseObject.put(ChapsModel.PARSE_FIELD_LINK_CHAP,
chapsModel.get(i)
.getLinkChap());
parseObject.put(ChapsModel.PARSE_FILED_TEAM_TRANSLATE,
chapsModel.get(i)
.getTeamTranslate());
parseObject.put(ChapsModel.PARSE_FIELD_OBJECT_MANGA,
ParseObject.createWithoutData(MangaModel.PARSE_OBJECT,
chapsModel.get(i)
.getObjectManga()));
parseObject.saveInBackground(new SaveCallback() {
#Override
public void done(final ParseException e) {
if (e == null) {
Log.e(">>>>>",
"done" + ojectId);
// parseObject.setObjectId(ojectId);
} else {
Log.e(">>>>>",
"else" + e.getMessage());
}
}
});
Log
java.lang.RuntimeException: objectIds cannot be changed in offline mode.
Log:
Sorry my english. thank
It's not possible to set objectId with Parse.com with primary key.
Although parse.com doesn't allow us to set the objectId of a row, you can create a new column named anything you want and you can set that new column to any objectId you want. For example, you can create a new column named myObjectId and set it to a string.
From the parse.com website at https://www.parse.com/docs/js/guide#cloud_code
The Data Browser
The Data Browser is the web UI where you can update and create objects in each of your apps. Here, you can see the raw JSON values that are saved that represents each object in your class.
When using the interface, keep in mind the following:
The objectId, createdAt, updatedAt fields cannot be edited (these are set automatically).

How to make sure that Data are saved in Parse.com and ready to be retrieved Android

I'm using Parse.com for developing a small application.
In a couple of actives i'm inserting values to a Class, and Immediately after that i'm Retrieving the values inserted from the previous activity, it's showing Error, it seems that it takes some seconds to save before being able to retrieve.
so i'm asking how can I know that the saved has been completed with Parse. is there any callback function which can let me know, so I would be able to retrieve that information
here is the code where i'm saving values
ParseUser user = ParseUser.getCurrentUser();
ParseQuery<ParseObject> query = ParseQuery.getQuery("test");
query.whereEqualTo("user", user.getUsername());
query.getFirstInBackground(new GetCallback<ParseObject>() {
public void done(ParseObject object, ParseException e) {
if (object == null) {
} else {
file = new ParseFile("profil.png", image);
file.saveInBackground();
object.put("name", nom.getText().toString());
object.put("Profil",file);
object.saveInBackground();
}
I have found an answer to my question
https://parse.com/docs/android/api/com/parse/SaveCallback.html
thank to Bjorn Kaiser

Access New ParseObject (Parse.com) Across Activities (Android)

I'm looking for a way to access a newly created local ParseObject which hasn't yet synced to the Parse cloud server. Since there is no objectId value there's no way to query for the objectId through the local datastore and it appears the localId (which looks like it creates a unique identifier locally) is locked down (otherwise this would be a non-issue as I could use my Content Provider to take care of the details). Since the ParseObject class isn't Serializable of Parcelable I can't pass it through an Intent. To note the complexity of my task I have I have 3 levels of ParseObjects (ParseObject > Array[ParseObjects] > Array[ParseObjects]). Essentially I'm looking to see if Parse has full offline capabilities.
TL:DR
Basically I want to be able to access a single ParseObject in a different Activity as soon as it's created. Does this problem have a practical application with Parse and ParseObjects or am I going to have to implement some serious work arounds?
I believe ParseObjects are serializable, so put them into a Bundle and then put that Bundle into an Intent
in the current activity
Intent mIntent = new Intent(currentActivityReference, DestinationActivity.class);
Bundle mBundle = new Bundle();
mBundle.putSerializable("object", mParseObject);
mIntent.putExtras(mBundle);
startActivity(mIntent);
in the destination activity
retrieve the intent with getIntent().getExtras(), which is a Bundle object, so there is a getter for the serializable .getSerializable("object") but you will have to cast it to (ParseObject)
So I was able to keep everything within the confines of the structures I already have in place to take care of this problem (a sync adapter and the Parse API). Basically all I had to do was leverage Parse's existing "setObjectId" function.
NOTE: This only works with an existing Content Provider / SQLiteDatabase
I created a temporary unique ID for the new ParseObject to be stored locally. This unique value is based off of the max index number in the Content Provider I'm storing my objects (for my Sync Adapter).
//query to get the max ID from the Content Provider (used with the sync adapter)
Cursor cursor = context.getContentResolver().query(
WorkoutContract.Entry.CONTENT_URI,
new String[]{"MAX(" + WorkoutContract.Entry._ID + ")"},
null, null, null
);
long idx = 1; //default max index if there are no records
if (cursor.moveToFirst())
idx = cursor.getInt(0) + 1;
final long maxIndex = idx;
cursor.close();
//this is the temporary ID used for storing, a String constant prepended to the max index
String localID = WorkoutContract.LOCAL_WORKOUT_ID + maxIndex;
I then used the pin() method to store this ParseObject locally and then made an insert into the Content Provider to not only keep the ID in the table to iterate the max index in the table.
//need to insert a dummy value into the Content Provider so the max _ID iterates
ContentValues workoutValues = new ContentValues();
//the COLUMN_WORKOUT_ID constant refers to the column which holds the ParseObjects ID
workoutValues.put(WorkoutContract.Entry.COLUMN_WORKOUT_ID, localID);
context.getContentResolver().insert(
WorkoutContract.Entry.CONTENT_URI,
workoutValues);
Then I created another dummy ParseObject with all the same attributes as the one with the local ID (without the local ID). This ParseObject was then saved to the server via the saveEventually() function. (Note: This will create 2 local copies or your ParseObject. To leave the blank copy out of queries simply leave out ParseObjects with null object IDs).
query.whereNotEqualTo("objectId", null);
In the saveEventually() function there needs to be a callback which replaces the old (local) ParseObject as well as the localID value in the Content provider. In the SaveCallback object replace the server returned ParseObject's attributes with the local ones (to account for any changes made during the server query). Below is the full code for the SaveCallback where the tempObject is the one sent to the Parse server:
tempObject.saveEventually(new SaveCallback() {
//changes the local ParseObject's ID to the newly generated one
#Override
public void done(ParseException e) {
if (e == null) {
try {
//replaces the old ParseObject
tempObject.put(Workout.PARSE_FIELD_NAME, newWorkout.get(Workout.PARSE_FIELD_NAME));
tempObject.put(Workout.PARSE_FIELD_OWNER, ParseUser.getCurrentUser());
tempObject.put(Workout.PARSE_FIELD_DESCRIPTION, newWorkout.get(Workout.PARSE_FIELD_DESCRIPTION));
tempObject.pin();
newWorkout.unpinInBackground(new DeleteCallback() {
#Override
public void done(ParseException e) {
Log.i(TAG, "Object unpinned");
}
});
} catch (ParseException e1) {
e1.printStackTrace();
}
//update to content provider with the new ID
ContentValues mUpdateValues = new ContentValues();
String mSelectionClause = WorkoutContract.Entry._ID + "= ?";
String[] mSelectionArgs = {Long.toString(maxIndex)};
mUpdateValues.put(WorkoutContract.Entry.COLUMN_WORKOUT_ID, tempObject.getObjectId());
mUpdateValues.put(WorkoutContract.Entry.COLUMN_UPDATED, tempObject.getUpdatedAt().getTime());
context.getContentResolver().update(
WorkoutContract.Entry.CONTENT_URI,
mUpdateValues,
mSelectionClause,
mSelectionArgs
);
}
}
});
To get the local ParseObject in another Activity just pass the local objectId in an Intent and load it. However, the index of the ParseObject on the Content Provider needs to be passed as well (or it can be retrieved from the unique local ID) so if the ParseObject is ever retrieved again you can check the Content Provider for the updated Object ID and query the correct ParseObject.
This could use a bit of refinement but for now it works.

How to get objectId on Parse.com android

It is said that we can retrieve our data if we are having objectId for that particular row, but it is auto generated and we cant insert it while setting data , so how to get data if i am not having object id , or any other means so that i can set objectId on my means.
Code is here as in comment:
ParseObject gameScore = new ParseObject("My Parse File");
String objectId = gameScore.getObjectId();
ObjectId doesnt't exist until a save operation is completed.
ParseObject gameScore = new ParseObject("My Parse File");
To retrieve the object id you need to save the object and register for the save callback.
gameScore.saveInBackground(new SaveCallback <ParseObject>() {
public void done(ParseException e) {
if (e == null) {
// Success!
String objectId = gameScore.getObjectId();
} else {
// Failure!
}
}
});
ObjectId can be retrieved from the original ParseObject(gameScore) once the done save callback is fired.
You can use this for getting current user object id
ParseUser pUser= ParseUser.getCurrentUser();
String objId= pUser.getObjectId();
not sure if this will apply to android , but I was trying to retreive the objectid, but for an entry that is already created. I did something like this and it worked.
ParseObject gameScore = new ParseObject("My Parse File");
var obId = gameScore.id;
Got it from the Javascript docs on Parse.com
The three special values are provided as properties:
var objectId = gameScore.id;
var updatedAt = gameScore.updatedAt;
var createdAt = gameScore.createdAt;
You can't unfortunately use the ObjectId until the object's been saved. I'm having this same problem now. The only solution I can think of, and posted a similar question relating to it here
My solution would be to make a tempId on the object and refer to that locally until it has an actual ObjectId, perhaps using a saveInBackground or saveEventually() callback to set other objects relating to it, to it's newly created ObjectId instead of it's old temp one.. when it's made available
It takes times for your values to be stored in table. Use this to get ObjectId
gameScore.saveInBackground(new SaveCallback() {
public void done(ParseException e) {
if (e == null) {
// Saved successfully.
Log.d("main", "User update saved!");
Log.d("main", "ObjectId "+gameScore.getObjectId());
} else {
// The save failed.
Log.d("main", "User update error: " + e);
}
}
});
In case you're handling the thread yourself:
First save:
gameScore.save();
Then you'll be able to access the id:
String parseId = gameScore.getObjectId();

Categories

Resources