How to join two tables in firebase? - java

I created one table has studId, studName, place.I also want to create another table related to the first one that has studId, day, timeone, timeTwo. How can I do it? I'm a beginner in firebase
this method will add the data for firebase
private void addDate(){
String studName = userName.getText().toString().trim();
String place = spinnerPlace.getSelectedItem().toString();
if(!TextUtils.isEmpty(studName)){
String id = databaseStudentData.push().getKey();
StudentData studentData = new StudentData(id, studName, place);
databaseStudentData.child(id).setValue(studentData);
addDay(id);
Toast.makeText(this, "Data is saved", Toast.LENGTH_LONG).show();
}else {
Toast.makeText(this, "you Should Enter your name", Toast.LENGTH_LONG).show();
}
}
and here the data that i stored
enter image description here

There is no benefit in creating another table just for one attribute, what you can do is the following. Since you already did this:
String id = databaseStudentData.push().getKey();
StudentData studentData = new StudentData(id, studName, place);
databaseStudentData.child(id).setValue(studentData);
Now to add time under this table you can do the following:
Map<String, Object> childUpdates = new HashMap<>();
childUpdates.put("time", time);
databaseStudentData.child(id).updateChildren(childUpdates);
This way you will have the following database:
id
studId : "id"
studName : "name"
studPlace : "place"
studTime : "time"

Related

How can i populate a RecyclerView with hashmap values?

Before i used an ArrayList for this, but because of duplicate Album issues (which i resolved before API29 by using DISTINCT and GROUP BY statements) which are not allowed anymore to use inside a query.
I got values like this in my RecyclerViews Adapter: myArrayList.get(position).getAlbum();
But now that i'm using a HashMap, how can i get a value by position which i get from the adapter?
Code for adding values in Hashmap
HashMap<Integer, Album> albums = new HashMap<>();
String[] projection2 = { MediaStore.Audio.Media.ALBUM_ID,
MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.IS_MUSIC};
String selection = MediaStore.Audio.Media.IS_MUSIC + "!=0";
String sort = MediaStore.Audio.Media.ALBUM + " COLLATE NOCASE ASC";
cursor = resolver.query(musicUri, projection2, selection, null, sort);
try {
if (cursor != null) {
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
int columnAlbumId = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID);
int columnAlbumName = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM);
String albumId = cursor.getString(columnAlbumId);
String albumName = cursor.getString(columnAlbumName);
if(albums.containsKey(albumId) == false){
Album album = new Album(albumId, albumName);
albums.put(albumId, album);
}
cursor.moveToNext();
}
}
}catch (Exception e){
Log.e(TAG, "Exception caught when creating ALBUM!", e);
throw new Exception();
}
By definition the HashMap is not sorted so how about a SortedMap? An implementation of a SortedMap is a TreeMap which sorts the entries according to keys (or a Comparator).
I believe that suits you since your map has integers as keys.
Edit:
You can use a List or whatever collection suits you in your adapter. For example keep a reference to the ids and the albums which is the data that you're interested in displaying through the adapter.
private int[] ids;
private Album[] albums;
As you're passing the data (included in a map) to your adapter then you could extract that data and place it in the array containers so you can take advantage of the index. For example,
public MyAdapter(Map<Integer,Album> data){
ids = new int[map.size()];
albums = new Album[map.size()];
int i = 0;
for (Map.Entry<Integer,Album> e : map.entrySet()){
ids[i] = e.getKey();
albums[i++] = e.getValue();
}
}
Now that you have your arrays you can sort them also if you like and in case you want to grab the 3rd album and its id all you need to do is,
int id = ids[2];
Album album = albums[2];

Validating two strings

I'm trying to validate two strings via TextUtils.isEmpty but i'm failing everytime.
Following is my code:
private void addArtist() {
//getting the values to save
String email = editTextName.getText().toString().trim();
String mobileno = editTextName1.getText().toString().trim();
//checking if the value is provided
if (TextUtils.isEmpty(email)){
//if the value is not given displaying a toast
Toast.makeText(this, "Please enter email.", Toast.LENGTH_LONG).show();
}
else{
//getting a unique id using push().getKey() method
//it will create a unique id and we will use it as the Primary Key for our Artist
String id = databaseArtists.push().getKey();
//creating an Artist Object
Artist artist = new Artist(id, email, mobileno);
//Saving the Artist
databaseArtists.child(id).setValue(artist);
Toast.makeText(this, "Successful...", Toast.LENGTH_LONG).show();
}
}
Currently this code is working on string email, i want it to work with string mobileno also.Any help is appreciated.
Why don't you just try to use try catch block and inside it try to convert this string after you read from TextField control object into number if "Mobileno" variable should be int type? If it fails then you can in catch block make some other instructions to prevent from inserting it to field of specific object. Have you tried that?

How to return multiple List<String> via AsyncTask in android?

I have created an AsynTaskInsideActivity class that extends AsyncTask<Void, Void, List<String>> within the MainActivity as an inner class. I am using this AsynTaskInsideActivity for getting all the records from the location table. This location table has following columns:
location_id
country
state
zip_code
And I want to fetch records from each individual column. So, for storing every record of each individual column I created four List type arrays (i.e. one for each column) and successfully stored the retrieved Cursor data within each of them. Now, the problem is I need to return every column's records. So, to be specific how can I return those four individual List type arrays from a one AsyncTask class. Currently, I am returning only the list type array namely locationId which has all the location ids I fetched from location table's location_id column.
Questions:
How can I return multiple list array items from a single AsyncTask class? After all when we query a database, sometimes we need records from multiple columns from an individual table to process further operations.
Is there any better approach that I can use to overcome this problem? or I have to believe some things are really impossible.
This is what my AsyncTask class looks like:
public class AsyncTaskInsideActivity extends AsyncTask<Void, Void, List<String>> {
private static final String CLASS_TAG = AsyncTaskInsideActivity.class.getSimpleName();
#Override
protected List<String> doInBackground(Void... params) {
Log.v(CLASS_TAG, "AsyncTaskInsideActivity started successfully....");
SoCalledDbHelper soCalledDbHelper = new SoCalledDbHelper
(getBaseContext());
//key-value pairs for inserting data into the table
ContentValues soCalledValues = new ContentValues();
soCalledValues.put(SoCalledContract.LocationTable.COLUMN_CITY_NAME, "Kim Kardishian");
soCalledValues.put(SoCalledContract.LocationTable.COLUMN_STATE, "No Ass Holes");
soCalledValues.put(SoCalledContract.LocationTable.COLUMN_ZIP_CODE, 007);
//insert location data
soCalledDbHelper.addLocationData(soCalledValues);
//For storing the cursor data which will be retrieved by the read query.
Cursor locationDataCursor;
//Query for all the data in the location table
locationDataCursor = soCalledDbHelper.getAllLocationData(null, null, null, null);
List<String> sCLocationId = new ArrayList<String>();
List<String> sCCityName = new ArrayList<String>();
List<String> sCState = new ArrayList<String>();
List<String> sCZipCode = new ArrayList<String>();
if (locationDataCursor.getCount() > 0) {
//Reset the cursor location
locationDataCursor.moveToPosition(-1);
while (locationDataCursor.moveToNext()) {
//Extracting data from the location cursor
sCLocationId.add(locationDataCursor.getString
(locationDataCursor.getColumnIndex("_id")));
sCCityName.add(locationDataCursor.getString
(locationDataCursor.getColumnIndex("city_name")));
sCState.add(locationDataCursor.getString
(locationDataCursor.getColumnIndex("state")));
sCZipCode.add(locationDataCursor.getString
(locationDataCursor.getColumnIndex("zip_code")));
}
Log.i(CLASS_TAG, "Success: Cursor has data! #Total Records: " +
locationDataCursor.getCount());
for (String locationIds : sCLocationId) {
Log.i(CLASS_TAG, "Location Id: + " + locationIds);
}
for (String cityNamez : sCCityName) {
Log.i(CLASS_TAG, "City Names: + " + cityNamez);
}
for (String statesNames : sCState) {
Log.i(CLASS_TAG, "State Names: + " + statesNames);
}
for (String zipCodes : sCZipCode) {
Log.i(CLASS_TAG, "Zip Codes: + " + zipCodes);
}
} else {
Log.w(CLASS_TAG, "Error: Cursor is empty! #Total Records: " +
locationDataCursor.getCount());
}
locationDataCursor.close();
soCalledDbHelper.close();
Log.v(CLASS_TAG, "AsyncTaskDbHelper ended successfully....");
return sCLocationId;
}
}
You could just return extend your AsyncTask off of AsyncTask<Void, Void, List<List<String>> and be done with it but this is not the best approach.
A better approach would be to extend off of AsyncTask<Void, Void, List<Location>> where Location is defined as:
public class Location
{
private String location_id;
private String country;
private String state;
private String zip_code;
// Constructors, getters and setters go here. Your IDE should be able to generate them.
// You can also override the toString method to format the output better
}
Your loop would then look something like this:
List<Location> locations_list = new ArrayList<Location>();
if (locationDataCursor.moveToFirst()) {// Moves to first if cursor is not empty
do{
Location location = new Location();
//Extracting data from the location cursor
location.setID(locationDataCursor.getString
(locationDataCursor.getColumnIndex("_id")));
location.setCity(locationDataCursor.getString
(locationDataCursor.getColumnIndex("city_name")));
location.setState(locationDataCursor.getString
(locationDataCursor.getColumnIndex("state")));
location.setZip(locationDataCursor.getString
(locationDataCursor.getColumnIndex("zip_code")));
// Add location to the list
locations_list.add(location)
}while (locationDataCursor.moveToNext())
Log.i(CLASS_TAG, "Success: Cursor has data! #Total Records: " +
locationDataCursor.getCount());
for (Location l : locations_list) {
Log.i(CLASS_TAG, "Location: " + l.toString());
}
} else {
Log.w(CLASS_TAG, "Error: Cursor is empty!"
}
// Close any open DB objects
locationDataCursor.close();
soCalledDbHelper.close();
Log.v(CLASS_TAG, "AsyncTaskDbHelper ended successfully....");
// Return the list of locations
return locations_list;
Well, after researching for the solution to this question over the internet and devoting several hours for getting the single AsyncTask to return multiple values I came up with a solution with a nested List array i.e. List<List<String>>
Original Credits:
#Simon: Who gave me an indication (or hint) that how could I update my AsyncTask to get the job done, that was proved to be really helpful.
#VERT9x: Thanks for putting the effort and getting the job done with a different approach.
Solution:
public class AsyncTaskInsideActivity extends AsyncTask<Void, Void, List<List<String>>> {
private static final String CLASS_TAG = AsyncTaskInsideActivity.class.getSimpleName();
#Override
protected List<String> doInBackground(Void... params) {
Log.v(CLASS_TAG, "AsyncTaskInsideActivity started successfully....");
SoCalledDbHelper soCalledDbHelper = new SoCalledDbHelper
(getBaseContext());
//key-value pairs for inserting data into the table
ContentValues soCalledValues = new ContentValues();
soCalledValues.put(SoCalledContract.LocationTable.COLUMN_CITY_NAME, "Kim Kardishian");
soCalledValues.put(SoCalledContract.LocationTable.COLUMN_STATE, "No Ass Holes");
soCalledValues.put(SoCalledContract.LocationTable.COLUMN_ZIP_CODE, 007);
//insert location data
soCalledDbHelper.addLocationData(soCalledValues);
//For storing the cursor data which will be retrieved by the read query.
Cursor locationDataCursor;
//Query for all the data in the location table
locationDataCursor = soCalledDbHelper.getAllLocationData(null, null, null, null);
List<String> sCLocationId = new ArrayList<String>();
List<String> sCCityName = new ArrayList<String>();
List<String> sCState = new ArrayList<String>();
List<String> sCZipCode = new ArrayList<String>();
if (locationDataCursor.getCount() > 0) {
//Reset the cursor location
locationDataCursor.moveToPosition(-1);
while (locationDataCursor.moveToNext()) {
//Extracting data from the location cursor
sCLocationId.add(locationDataCursor.getString
(locationDataCursor.getColumnIndex("_id")));
sCCityName.add(locationDataCursor.getString
(locationDataCursor.getColumnIndex("city_name")));
sCState.add(locationDataCursor.getString
(locationDataCursor.getColumnIndex("state")));
sCZipCode.add(locationDataCursor.getString
(locationDataCursor.getColumnIndex("zip_code")));
}
Log.i(CLASS_TAG, "Success: Cursor has data! #Total Records: " +
locationDataCursor.getCount());
for (String locationIds : sCLocationId) {
Log.i(CLASS_TAG, "Location Id: + " + locationIds);
}
for (String cityNamez : sCCityName) {
Log.i(CLASS_TAG, "City Names: + " + cityNamez);
}
for (String statesNames : sCState) {
Log.i(CLASS_TAG, "State Names: + " + statesNames);
}
for (String zipCodes : sCZipCode) {
Log.i(CLASS_TAG, "Zip Codes: + " + zipCodes);
}
} else {
Log.w(CLASS_TAG, "Error: Cursor is empty! #Total Records: " +
locationDataCursor.getCount());
}
locationDataCursor.close();
soCalledDbHelper.close();
//Creating a List that can store List(s) within it.
//List of Lists String
List<List<String>> arrayOfLists = new ArrayList<List<String>>();
//Adding those Lists that was used to store each column records
arrayOfLists.add(sCLocationId);
arrayOfLists.add(sCCityName);
arrayOfLists.add(sCState);
arrayOfLists.add(sCZipCode);
//Start iterating over the parent arrayOfLists List
for(int i = 0; i < arrayOfLists.size(); i++) {
//Print each arrayOfLists data item it contains
Log.v(CLASS_TAG, "Parent List: " + arrayOfLists.get(i).toString());
//Start iterating over child of arrayOfLists List
for(int j = 0; j < arrayOfLists.get(i).size(); j++) {
//Print each arrayOfLists CHILD data item it contains
Log.v(CLASS_TAG, "Child List: " + arrayOfLists.get(i).get(j).toString());
}
}
//Size of the arrayOfLists
Log.v(CLASS_TAG, "Parent List Size: " + Integer.toString(arrayOfLists.size()));
//Size of the arrayOfLists child container
Log.v(CLASS_TAG, "Child List Size: " + Integer.toString(arrayOfLists.get(1).size()));
Log.v(CLASS_TAG, "AsyncTaskDbHelper ended successfully....");
return arrayOfLists;
}
Changes I Made:
Changed the 3rd parameter of AsyncTask class and doInBackground() return type to List<List<String>>, so it can return multiple values.
For solution see under these two lines:
locationDataCursor.close();
soCalledHelper.close();

how to add and get class's object values in HashMap

I want to create a method to add data into sqlite database which take HashMap<String,Person> as argument in a class.
From another class, I want to add person details in HashMap<String,Person> that can be used by my database handler class.
I have search a lot and tried many examples for this, but couldn't get the solution. Now i'm bit confused how to do this.
I am doing this in following manner now, and getting ClassCastException.
Class 1 :PersonDataSource.java
public long createContact(HashMap<String, Contact> queryValues) {
ContentValues values = new ContentValues();
Contact val = Contact.class.cast(queryValues);
values.put( MySQLiteHelper.COLUMN_FIRST_NAME, val.getFirstName());
values.put( MySQLiteHelper.COLUMN_LAST_NAME, val.getLastName());
values.put( MySQLiteHelper.COLUMN_NICK_NAME, val.getNickName());
values.put( MySQLiteHelper.COLUMN_BIRTHDATE, val.getBirthDate());
values.put( MySQLiteHelper.COLUMN_PRIMARY_CONTACT, val.getPrimaryContact());
long insertId = database.insert(MySQLiteHelper.TABLE_NAME, null, values);
return insertId;
}
And form another class :
datasource = new ContactDataSource(this);
datasource.open();
Cursor phones = getContentResolver().query(Phone.CONTENT_URI, PROJECTION,null,null, Phone.DISPLAY_NAME);
while (phones.moveToNext())
{
String name=phones.getString(phones.getColumnIndex(Phone.DISPLAY_NAME));
String phoneNumber = phones.getString(phones.getColumnIndex(Phone.NUMBER));
Person data = new Person();
data.setNickName(name);
data.setPrimaryContact(phoneNumber);
HashMap<String, Person> map = new HashMap<String, Person>();
map.put("data", data);
long id = datasource.createContact(map);
Log.e(CLASS_NAME, "Contact id :" + String.valueOf(id));
}
phones.close();
datasource.close();
How can i solve this ?
Use
Contact val = (Contact) queryValues.get("data");
Instead of
Contact val = Contact.class.cast(queryValues);
This is because, you are trying to put a single contact into map as map.put("data", data); so when you will read this entry, you need to use map.get("data") because here key is data.

Getting data from a HashMap into SQLite database

In my app I am retrieving records from a server. The records are in an xml file. I'm able to get the file down and parse it without any trouble. I'm storing the results in a HashMap and I'd like to be able to put those results into my app's SQLite database.
Here's the code for the HashMap
ArrayList<HashMap<String, String>> StudentDownloads = new ArrayList<HashMap<String, String>>();
String xml = XMLfunctions.getXML(target);
Document doc = XMLfunctions.XMLfromString(xml);
if(XMLfunctions.XMLfromString(xml)==null){
Toast.makeText(this, "Badly Formed File", Toast.LENGTH_LONG).show();
finish();
}
int numResults = XMLfunctions.numResults(doc);
if((numResults <= 0)){
Toast.makeText(this, "There Were No Student Results To Show", Toast.LENGTH_LONG).show();
finish();
}
NodeList nodes = doc.getElementsByTagName("Students");
for (int i = 0; i < nodes.getLength(); i++) {
HashMap<String, String> map = new HashMap<String, String>();
Element e = (Element)nodes.item(i);
map.put("Student Id", "Student Id " + XMLfunctions.getValue(e, "StudentId"));
map.put("Student Type", "Student Type" + XMLfunctions.getValue(e, "StudentType"));
map.put("Student Location", "Student Location" + XMLfunctions.getValue(e, "StudentLocation"));
map.put("Student Mother", "Student Mother" + XMLfunctions.getValue(e, "StudentMother"));
StudentDownloads.add(map);}
};
Now in my app, I have already created a data entry form that uses a class called StudentRecord, in my entry form I use this function to update the file
private void addStudent(StudentRecord newRecord){
mDB.beginTransaction();
try {
ContentValues StudentRecordToAdd = new ContentValues();
StudentRecordToAdd.put(Students.STUDENT_ID, newRecord.getStudentName());
StudentRecordToAdd.put(Student.STUDENT_TYPE, newRecord.getStudentType());
StudentRecordToAdd.put(Student.STUDENT_LOCATION, newRecord.getStudentLocation());
StudentRecordToAdd.put(Student.STUDENT_MOTHER, newRecord.getStudentMother());
mDB.insert(Student.STUDENT_TABLE_NAME,Student.STUDENT_ANIMALID, StudentRecordToAdd);
mDB.setTransactionSuccessful();
Toast.makeText(this,"Recorded Added ",0).show();
} finally {
mDB.endTransaction();
}
What's the best way to get my values from the HashMap to my NewRecord function? I've been looking at so long I think I've gone brain dead.
Thank you
If i'm reading you right, it sounds like you need to move your addStudent function from the form/activity where it lives right now into some kind of "helper" class:
private class dbHelper {
Database mDB; // set this up however you are doing it already
private void addStudent(StudentRecord newRecord){
mDB.beginTransaction();
try {
ContentValues StudentRecordToAdd = new ContentValues();
StudentRecordToAdd.put(Students.STUDENT_ID, newRecord.getStudentName());
StudentRecordToAdd.put(Student.STUDENT_TYPE, newRecord.getStudentType());
StudentRecordToAdd.put(Student.STUDENT_LOCATION, newRecord.getStudentLocation());
StudentRecordToAdd.put(Student.STUDENT_MOTHER, newRecord.getStudentMother());
mDB.insert(Student.STUDENT_TABLE_NAME,Student.STUDENT_ANIMALID, StudentRecordToAdd);
mDB.setTransactionSuccessful();
Toast.makeText(this,"Recorded Added ",0).show();
} finally {
mDB.endTransaction();
}
}
}
And then just make calls to that helper when you've parsed your XML
ArrayList<StudentRecord> StudentDownloads = new ArrayList<StudentRecord>();
for (int i = 0; i < nodes.getLength(); i++) {
Element e = (Element)nodes.item(i);
int id = Integer.valueOf(XMLfunctions.getValue(e, "StudentId")));
int type = Integer.valueOf(XMLfunctions.getValue(e, "StudentType")));
String location = XMLfunctions.getValue(e, "StudentLocation"));
String mother = XMLfunctions.getValue(e, "StudentMother"));
StudentRecord newRecord = new StudentRecord(id, type, location, mother);
StudentDownloads.add(newRecord);
}
And then when you're done processing:
for (StudentRecord s : StudentDownloads) {
mDBHelper.addStudent(s);
}

Categories

Resources