I have two tables in data base. One is user ad the second is transaction that have pointer to the first user, pointer to the second user and int. When I try make and display list I have error. I want to display all rows that CurrentUser is in first column:
ParseUser cu = ParseUser.getCurrentUser();
query.whereEqualTo("first", cu);
and list it with firstUser, secondUser and int:
from Adapter:
ParseObject taskObject = mTask.get(position);
ParseUser first = taskObject.getParseUser("first");
holder.firsthp.setText(first.getUsername());
ParseUser second = taskObject.getParseUser("second");
holder.secondhp.setText(second.getUsername()); //this line make error
int ile = taskObject.getInt("ile");
holder.taskhp.setText(Integer.toString(ile));
return convertView;
This is how transakcja table looks: http://i.stack.imgur.com/yh83p.png
When I saving transaction (when transaction table is clear, don't have any records) and immediately read it works but when I logout and login it crashes.
And here is entire code for toDoActivity Task Adapter and hplayout:
I had problems with pasting code here so I pasted it on pastebin
http://pastebin.com/2wtQLJXE
I think I know the problem. When you are calling your query on the transaction table, the two User's are Pointers to ParseObjects, or ParseUsers in this case. You need to ensure that these objects are FETCHED as well by the ParseQuery in order to properly access their data. They are ParseObjects with data from another table, Parse does not automatically retrieve them so you must tell Parse to do so when you need that data.
Looking at ParseQuery documentation for Android we find the include method.
public ParseQuery include(String key)
Include nested ParseObjects for the provided key.
You can use dot notation to specify which fields in the included object that are also fetched.
You want to use this to include columns names to Pointers of ParseObjects so the query fetches them at the same time as fetching the rest of the data from the table, in this case your transaction table.
Add this:
ParseQuery<ParseObject> query = ParseQuery.getQuery("transakcja");
query.whereEqualTo("first", cu);
query.addDescendingOrder("createdAt");
query.include("first");
query.include("second");
The reason first is having no null issues, is it is the Pointer to the current ParseUser logged in, which doesn't need to be fetched as it's data is accessible. The second one is not fetched, therefore adding the include to the query SHOULD fix this :). Make sure to also include the column "first" because I'm sure your future ParseQuery's will not always be between the current user and non-current second user
Related
I have a users collection with uId, name, photo
I have a visits collection with uId, userId, location
I have a recyclerview in which I want to show the location with the user name and photo
Can I use the reference field type? If so, how will Firestore know to link visits.userId == users.uId ?
Maybe I first need to query all the visits and then query the relevant user but 2 things:
It means querying a lot of times.
I didn't understand how to collect the joined collection into the adapter, which is based on one query?
Please advice
Thanks
current code
visitsList = db.collection("visitsList");
Query query = visitsList.whereEqualTo("userId",prefs.getString("id","")).orderBy("visitDate", Query.Direction.ASCENDING);
FirestoreRecyclerOptions<AVisit> options = new FirestoreRecyclerOptions.Builder<AVisit>().setQuery(query, AVisit.class).build();
adapter = new VisitsListAdapter(options, VisitsListActivity.this);
RecyclerView rv = findViewById(R.id.rvVisitsList);
rv.setHasFixedSize(true);
rv.setLayoutManager(new LinearLayoutManager(this));
rv.setAdapter(adapter);
The code is a simple query from the collection, not sure how to get the name and photo from the userId field in that collection.
Can I use the reference field type?
Yes, you can use a reference field.
If so, how will Firestore know to link visits.userId == users.uId ?
Firestore results always comes from a single collection (at the moment). It does not automatically join the document from the users collection when you're reading from the visits collection. You will have to do this yourself.
That indeed means you'll be executing multiple reads, but it's often not nearly as slow as you may think. See Google Firestore - how to get document by multiple ids in one round trip?
Update: To show data from the user profile in a list of visits, there are two main options:
load the additional user document in populateView or with a custom parseSnapshot implementation.
duplicate the relevant user data in the visits collection (which is quite normal in NoSQL databases). Also see Alex' answer here: indexed query with FirestoreRecyclerAdapter.
I'm trying to get a reference to the fist item in a firebase "Array"
In my case it would be "ElmmycgjS1Nvq.../albums/-IrdMMds"
But I'm not sure how to contsturct the query:
dbRef.child("ElmmycgjS.../albums").???.child("name"); // = "Brothers in Arms"
Where ??? should be something like getFirst().
Suppose I don't know the Id of the first Album beforehand (-IrdMMds). I just need to get the first one. I've tried limitToFirst(1).getRef() but this didn't help.
You'll want a query that listens for the first child:
Query first = dbRef.child("ElmmycgjS.../albums").limitToFirst(1);
And then attach a listener to that query.
When you execute a query against the Firebase Database, there will potentially be multiple results. So the result of the query will be a list of those results. Even if there is only a single result, the it will be a list of one result.
The goal is : after a user has been logged in , the next activity should display his list of courses.
There is a table of courses in Parse's cloud, but how can I retrieve the correct courses (current user's courses) ?
I've thought of 2 approaches :
1. using getCurrentUser method - but what if there are more than one user in the cache ?
2. save for each course the userName that saved it , and then query for that userName - but how should I know that the currentUser method will return the correct user ?
How can I solve this problem ?
using getCurrentUser method - but what if there are more than one user in the cache ?
There's always one currently logged in user and ParseUser.getCurrentUser() will get it. Well, unless there is no logged in user.
but how should I know that the currentUser method will return the correct user
As above. I don't get what you're confused about.
There is a table of courses in Parse's cloud, but how can I retrieve the correct courses (current user's courses)
and
save for each course the userName that saved it , and then query for that userName - but how should I know that the currentUser method will return the correct user ?
I can think of two approaches here. There may be more. Up to you what you decide to use.
So you have the _User table and the Course table. You can do one of the following:
Add a courses array to each _User and for each _User, store their list of courses there. It should be a list of objectIds, so basically you'll have the ID's of all the courses that _User is registered for. Each Parse object has a limited size in the database so you should use it if you are sure you won't need big amounts of data for each user. If you want to retrieve this, query the _User table by the id of the user and fetch the list of courses.
The "relational" approach: add an UserCourse table that has a userId and a courseId column. Every time you want to add a course for a particular user, you add a new entry in here that holds the id of that user and the id o the course. Similarly to the above, have a query that fetches all the stuff from UserCourse by userId. Note that in this case you'll also need to make sure your query fetches the data from _User and Course. Otherwise you'll just end up with UserCourse entries, which merely store ID's.
I have two tables (Classes):
StudentInformation: with columns RollNumber, address, name, school
StudentMarks : with columns RollNumber, Marks1, Marks2, Marks3
I've been able to save the data from a single form into these two simultaneously, but not getting a clue on how to put a query while retrieving into a listview or any other view something like
'return rows (from both tables together) where roll number = 1234' / 'return rows (from both tables together) where Marks2 > 50'
I'm using Parse.com backend for Android
Kindly help
Thanks
First, the UI aspect of showing in a ListView is provided by ParseQueryAdapter. https://parse.com/docs/android_guide#ui-queryadapter
Regarding the query, I do not think you can join tables in the way you want. Instead, you could create a pointer in StudentMarks to StudentInformation.
Then you can query something like:
ParseQuery<ParseObject> query = ParseQuery.getQuery("StudentMarks");
query.include('studentInformation'); // include the pointer to get StudentInformation
query.whereEqualTo("RollNumber", 1234);
query.whereGreaterThan("Marks2", 50);
... // perform query
In the results StudentInformation will be available like this:
List<ParseObject> objects; // the result from the query
ParseObject studentMark = objects.get(0); // example using first object
ParseObject studentInformation = studentMark.get("studentInformation");
String studentName = studentInformation.get("name");
String studentAddress = studentInformation.get("address");
... // etc
Alternatively you could also store a Relation of StudentMarks on StudentInformation, just to let you know that this is also an option, though I do not feel like it fits your current need as well as the solution presented above.
I have a really different situation. I have a form where user fills the data and insert into database. Now in the same form, I need to update his data also. Something like, there is a search user autocomplete text view. When user finds him then the data from database directly fills all the form fields. Now, either he submits data with the same info, if his info has not changed or, if the info has changed, he changes only some of the fields and then press the same button(submit) to update his data. I am doing so because I need to register the user in different particular session. He can register many times with same data. But when his some of the data is changed, I need to update his data but with registering him in the session with new id.
I do not want to provide you my codes here, I just need some technical help, how can I achieve the solution of this problem? If I am not wrong, I am thinking to use TextWatcher. I can implement textwatcher in each edittext form. When the text is changed, somehow the button(submit) that is used to insert get some connection with textwatcher, that it should update the database instead insert.
I am not sure if I am right. Help me please if you have some easy and reliable method to do. Thanks!!
You must have created a method in the Activity or a method in a separate class(I would prefer a separate class for database related methods). And you must keep some registration id or something which should match every time.
Suppose the registration id is named as ID. When you are inserting the data check within that insert method whether this ID matches with any previous records or not. If it matches then do update instead of insert.
Something like:
SQLiteDatabase objSqliteDB = DatabaseHelper.openDataBase();
objSqliteDB.beginTransaction();
SQLiteStatement stmtRecCount = objSqliteDB.compileStatement("select count(*) from ID where ID =?");
stmtRecCount.bindString(1, ID);
long count = stmtRecCount.simpleQueryForLong();
if(count != 0)
{
stmtUpdate.bindString(1, Name);
. . .
stmtUpdate.execute();
}
else
{
stmtInsert.bindString(1, Name);
. . .
stmtInsert.executeInsert();
}
Add whatever other fields you need to update
stmtInsert
&
stmtUpdate
will be yourinsert and update query