How to search in multiple child in FirebaseRecyclerOptions - java

I have this code that get the value from an edit text and search it in firebase real time database, the problem is that I want to search the string in multiple child in the data base
private void searchProcess(String s) {
FirebaseRecyclerOptions<Product> options =
new FirebaseRecyclerOptions.Builder<Product>()
.setQuery(FirebaseDatabase.getInstance().getReference().child("Products").orderByChild("name").startAt(s).endAt(s+"\uf8ff"), Product.class)
.build();
productAdapter =new imageAdapter(options);
productAdapter.startListening();
recyclerView.setAdapter(productAdapter);
}
as you can see it only search by name, is there anyway so I can make it search in three Childs of the product class
public Product(String name, String type, String description, String owner, float price, String date, String downloadURL) {
this.name = name;
this.type = type;
this.description = description;
this.owner = owner;
this.price = price;
this.date = date;
this.downloadURL = downloadURL;
this.status = "Pending";
}

Related

is convertion to DTO like this ok or it is a bad practice?

I have Entity that has list of another entities inside. Same for DTO, dto object with a list of another dto.
I need to convert Entity to DTO with the list inside.
Here how it looks with streams ( a bit messy, don't know if it is ok to use ):
public List<RestaurantDto> getAll() {
List<Restaurant> restaurantList = restaurantRepository.findAll();
return restaurantList.stream()
.map(restaurant -> new RestaurantDto(restaurant.getName(), restaurant.getAddress(),
restaurant.getDishes().stream()
.map(dish -> new DishDto(dish.getId(), dish.getName(), dish.getPrice(), dish.getRestaurant()))
.collect(Collectors.toList())))
.collect(Collectors.toList());
}
Here is my DTO
#Getter
#Setter
#NoArgsConstructor
public class RestaurantDto {
private String name;
private String address;
private List<DishDto> dishes;
private int votes;
public RestaurantDto(String name, String address) {
this.name = name;
this.address = address;
}
public RestaurantDto(String name, String address, List<DishDto> dishes) {
this.name = name;
this.address = address;
this.dishes = dishes;
}
public void addDish(DishDto dishDto) {
dishes.add(dishDto);
}
public List getDeishes() {
return Collections.unmodifiableList(dishes);
}
}
And DTO that is in List
#Getter
#Setter
#NoArgsConstructor
#ToString
public class DishDto {
private int id;
#NotBlank
private String name;
#Digits(integer = 12, fraction = 2)
private double price;
private String restaurantName;
private String restaurantAddress;
#Digits(integer = 12, fraction = 0)
private int restaurantId;
public DishDto(int id, String name, double price, int restaurantId) {
this.id = id;
this.name = name;
this.price = price;
this.restaurantId = restaurantId;
}
public DishDto(int id, String name, double price, Restaurant restaurant) {
this.id = id;
this.name = name;
this.price = price;
this.restaurantName = restaurant.getName();
this.restaurantAddress = restaurant.getAddress();
this.restaurantId = restaurant.getId();
}
}
I do appreciate your help a lot!
In my opinion, retrieving the whole entity and then converting it to DTOs in order to have fewer fields can be considered as an anti-pattern.
You should use projections if you want to retrieve less fields from the entity.
Bringing all the fields to the memory and then using just couple of them is not a good idea.
Take a look at projections. The following resources may help:
https://vladmihalcea.com/the-best-way-to-map-a-projection-query-to-a-dto-with-jpa-and-hibernate/
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections

How do I go about creating the method?

I'm currently trying to create a class in java, to this specification:
I'm not sure how to create "ratings" since I'm seeing its using some
map function using the input of a string and an integer.
Here's my code so far:
public class Movie {
String ID;
String Name;
String Description;
String Genre[];
String Directors[];
String Actors[];
String Language;
String CountryOfOrigin;
}
Please create different objects for genre, director, actor and rating. It will be a best practice when you try to add more information to each entity.
Use access modifier "private" to each attribute and implement get,set methods as required.
Use ArrayLists instead of arrays to avoid resizing efforts when required.
import java.util.ArrayList;
import java.util.List;
public class Genre {
private int id;
private String name;
public Genre(int id, String name) {
this.id = id;
this.name = name;
}
}
public class Director {
private int id;
private String name;
public Director(int id, String name) {
this.id = id;
this.name = name;
}
}
public class Actor {
private int id;
private String name;
public Actor(int id, String name) {
this.id = id;
this.name = name;
}
}
public class Rating {
private int value;
private String name;
public Actor(int value, String name) {
this.value = value;
this.name = name;
}
}
public class Movie {
private int id;
private String name;
private String description;
private List<Genre> generes;
private List<Director> directors;
private List<Actor> actors;
private String language;
private String countryOfOrigin;
pulic Movie(int id, String name, String description, String language, String countryOfOrigin){
this.id = id;
// set other variables
this.actors = new ArrayList<Actor>();
// create other lists
}
public void addGenere(Genre genere){
this.generes.add(genere);
}
// implement other add methods to lists
}

How to fix NumberFormatException when using gson.fromJson

I have an arraylist saved in shared preferences, of custom objects (Book) and now that I've updated the app (added a new property called Progress, which is an int), it seems that gson is trying to put one of the longs into this int variable.
This only happens to select users, who download the app through the store and I haven't been able to reproduce it. I posted something similar but without enough information here yesterday and realised I posted too early.
Note: at myrr.auto1.myreadingrecord1.sharedFunctions.loadArrayList(sharedFunctions.java:40) is the
bookList = gson.fromJson(json, type);
line
static ArrayList<Book> loadArrayList(Context context) {
ArrayList<Book> bookList;
SharedPreferences mPrefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
Gson gson = new Gson();
String json = mPrefs.getString("finishedBooks", "");
if (json.isEmpty()) {
bookList = new ArrayList<>();
} else {
Type type = new TypeToken<ArrayList<Book>>() {
}.getType();
bookList = gson.fromJson(json, type);
}
return bookList;
}
Fatal Exception: com.google.a.r: java.lang.NumberFormatException: Expected an int but was 1538513480946 at line 1 column 1891 path $[0].i
at com.google.gson.internal.bind.TypeAdapters$7.read(TypeAdapters.java:227)
at com.google.gson.internal.bind.TypeAdapters$7.read(TypeAdapters.java:217)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:129)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:220)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:41)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:82)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:61)
at com.google.gson.Gson.fromJson(Gson.java:888)
at com.google.gson.Gson.fromJson(Gson.java:853)
at com.google.gson.Gson.fromJson(Gson.java:802)
at myrr.auto1.myreadingrecord1.sharedFunctions.loadArrayList(sharedFunctions.java:40)
This is how the json string looks like, in old versions:
{"author":"Kerry Cohen Hoffmann",
"categories":"Juvenile Fiction",
"description":"Feeling neglected by her divorced parents and distant older sister, fourteen-year-old Jessica discovers how easily she is able to attract the attention of men and boys, without realizing the risks of her behavior.",
"endTime":1546742469961,
"imageURL":"http://books.google.com/books/content?id\u003d7wLjQH5_HjEC\u0026printsec\u003dfrontcover\u0026img\u003d1\u0026zoom\u003d5\u0026edge\u003dcurl\u0026source\u003dgbs_api",
"language":"en",
"moreInfoLink":"http://books.google.com/books?id\u003d7wLjQH5_HjEC\u0026dq\u003deasy\u0026hl\u003d\u0026as_pt\u003dBOOKS\u0026source\u003dgbs_api",
"pages":"176",
"startTime":1546553627662,
"title":"Easy"}
And this is the Book class properties, the setters and getters are pretty normal so i didnt include them.
public class Book implements Serializable{
private String author;
private String title;
private String pages;
private String imageURL;
private String description;
private String categories;
private String moreInfoLink;
private String language;
private int progress = 0;
private long startTime = 0L;
private long endTime = 0L;
public Book (String author, String title, String pages, String description, String imageURL, String categories, String moreInfoLink, String language) {
this.author = author;
this.title = title;
this.pages = pages;
this.description = description;
this.imageURL = imageURL;
this.categories = categories;
this.moreInfoLink = moreInfoLink;
this.language = language;
}
So for some, select users the fromJson tries to put the starttime or endtime value into the new progress property. How can I prevent this?
It should just create a new ArrayList of Book but it actually just crashes.
ADDING:
public void setEndTime(long endTime) {
this.endTime = endTime;
}
public void setStartTime(long startTime) {
this.startTime = startTime;}
theCRBook.setStartTime(Calendar.getInstance().getTimeInMillis());
As the error shows, you enabled the minifyEnabled in the build.gradle in order to obfuscate the code. In this case you need to do the #SerializedName("endTime"), #SerializedName("startTime") ... etc. for every variable you have in the model because the name of that variable will be changed on release versions.
public class Book implements Serializable {
#SerializedName("author")
private String author;
#SerializedName("title")
private String title;
#SerializedName("pages")
private String pages;
#SerializedName("imageURL")
private String imageURL;
#SerializedName("description")
private String description;
#SerializedName("categories")
private String categories;
#SerializedName("moreInfoLink")
private String moreInfoLink;
#SerializedName("language")
private String language;
#SerializedName("progress")
private int progress = 0;
#SerializedName("startTime")
private long startTime = 0L;
#SerializedName("endTime")
private long endTime = 0L;
public Book (String author, String title, String pages, String description, String imageURL, String categories, String moreInfoLink, String language) {
this.author = author;
this.title = title;
this.pages = pages;
this.description = description;
this.imageURL = imageURL;
this.categories = categories;
this.moreInfoLink = moreInfoLink;
this.language = language;
}
}
The exception states 1538513480946 is too large to fit into int, which is correct. It's a timestamp for 10/02/2018 # 8:51pm (UTC) and should be stored as long.
Perhaps you have an older version of Book class where startTime or endTime are declared as int and not long (or maybe just the setter parameter is int).
You can also use this class for your book class:
public class Book {
#SerializedName("author")
#Expose
private String author;
#SerializedName("categories")
#Expose
private String categories;
#SerializedName("description")
#Expose
private String description;
#SerializedName("endTime")
#Expose
private long endTime;
#SerializedName("imageURL")
#Expose
private String imageURL;
#SerializedName("language")
#Expose
private String language;
#SerializedName("moreInfoLink")
#Expose
private String moreInfoLink;
#SerializedName("pages")
#Expose
private String pages;
#SerializedName("startTime")
#Expose
private long startTime;
#SerializedName("title")
#Expose
private String title;
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getCategories() {
return categories;
}
public void setCategories(String categories) {
this.categories = categories;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public long getEndTime() {
return endTime;
}
public void setEndTime(long endTime) {
this.endTime = endTime;
}
public String getImageURL() {
return imageURL;
}
public void setImageURL(String imageURL) {
this.imageURL = imageURL;
}
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
public String getMoreInfoLink() {
return moreInfoLink;
}
public void setMoreInfoLink(String moreInfoLink) {
this.moreInfoLink = moreInfoLink;
}
public String getPages() {
return pages;
}
public void setPages(String pages) {
this.pages = pages;
}
public long getStartTime() {
return startTime;
}
public void setStartTime(long startTime) {
this.startTime = startTime;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
Just import gson in your book class:
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
After that, you can easily get some start/end time from your book array and convert it to date like this:
ArrayList<Book> books = loadArrayList(this);
Date date = new Date(books.get(0).getStartTime());
Log.i(TAG, "Date: " + date.toString());
You will get date from your json string:
Date: Thu Jan 03 17:13:47 EST 2019
Hope this can help you :)

Fetch data based on user id from MYSQL and display in recyclerview in android studio

So I have a database that contains 2 tables, one for user activities named tblactivity and the other named tblusers:
tblactivity contains multiple data for a user and I want to display entries in tblactivity in a recyclerview based on the logged-in user whose data I fetched from tblusers. tblactivity has userid column and I would like to know how to go about this.
EDIT: More Details:
So am using slim framework: DbConnect.php
//Method to get emails of a particular user
public function getActivity(){
$stmt = $this->con->prepare("SELECT id, userid, subject, message FROM tblactivity");
$stmt->execute();
$stmt->bind_result($id, $userid, $subject, $message);
$users = array();
while($stmt->fetch()){
$user = array();
$user['id'] = $id;
$user['userid'] = $userid;
$user['subject'] = $subject;
$user['message'] = $message;
array_push($users, $user);
}
return $users;
}
My index.php code
$app->get('/allactivity', function(Request $request, Response $response){
$db = new DbOperations;
$users = $db->getActivity();
$response_data = array();
$response_data['error'] = false;
$response_data['users'] = $users;
$response->write(json_encode($response_data));
return $response
->withHeader('Content-type', 'application/json')
->withStatus(200);
});
Now in android studio:
My Activity.java model:
public class Activity {
private int id;
private int userid;
private String subject;
private String message;
private String to;
public Activity(String subject, String message) {
this.id = id;
this.userid = userid;
this.subject = subject;
this.message = message;
this.to = to;
}
public int getId() {
return id;
}
public int getUserid() { return userid; }
public String getSubject() { return subject; }
public String getMessage() {
return message;
}
public String getTo() { return to; }
}
User.java Model
public class User {
private int id;
private String email;
private String firstname;
private String lastname;
private String companyname;
private String postcode;
private String city;
private String state;
private String phonenumber;
private String address1;
private String country;
private String status;
private int currency;
private String credit;
private String language;
private int email_verified;
public User(int id, String email, String firstname, String lastname, String companyname, String address1, String city,
String state, String postcode, String country, String phonenumber, String status, int currency, String credit,
String language, int email_verified) {
this.id = id;
this.email = email;
this.firstname = firstname;
this.lastname = lastname;
this.companyname = companyname;
this.address1 = address1;
this.city = city;
this.state = state;
this.postcode = postcode;
this.country = country;
this.phonenumber = phonenumber;
this.status = status;
this.currency = currency;
this.credit = credit;
this.language = language;
this.email_verified = email_verified;
}
public int getId() {
return id;
}
public String getEmail() {
return email;
}
public String getFirstName() {
return firstname;
}
public String getLastName() {
return lastname;
}
public String getCompanyName() { return companyname; }
public String getAddress1() {
return address1;
}
public String getCity() {
return city;
}
public String getState() { return state; }
public String getPostcode() {
return postcode;
}
public String getCountry() {
return country;
}
public String getPhonenumber() {
return phonenumber;
}
public String getStatus() { return status; }
public int getCurrency() { return currency; }
public String getCredit() {
return credit;
}
public String getLanguage() {
return language;
}
public int getEmail_verified() { return email_verified; }
}
I am using Retrofit client to get the json output from php.
#GET("allactivity")
Call<List<Activity>> getActivityData();
}
If I understood you correctly your question goes about data handling. Now there are two possibilities, if you have a local database on the device, then you will have to create a SQLLiteOpenHelper and pass in a SQL Query, in which you clarify what data you need an example could be:
SELECT * FROM tblactivity WHERE userid = 30;
In this case you would get all the info about the user with the id 30. Now if you have an online database, you have to write a php file, which allows you the communication with the sql database, if I add this here as well, it would go too far. Here is tutorial you could check out about that: https://www.w3schools.com/php/php_mysql_connect.asp
As soon as you have uploaded the php file via an ftp handler, you need to open an internet connection with a link like this: www.mydomain.com/database.php?userid=30 .
You pass in a restriction of which users you are in interested in. In your php file you can then get the data with:
$sql = "SELECT * FROM tblactivity WHERE userid = ".$_GET["userid"];
Then you need to read the incoming data and parse it. My choice is to use json_encode in your php file and to store the incoming data in the app as JSON. You will need to inform yourself about that as well, but it's not all too difficult.
If you have received the data, you need to create a custom object, where you store all the necessary information:
public class User {
public User(String name, int _id, String email){
//save the information in local variables
}
public String getName(){
return mName;
}
//Add more methods to get and set the different variables.
}
Then the next thing you have to do is create a custom Adapter to populate the items of the RecyclerView. But again, this would be too much to explain here. Here would be the link to another tutorial: https://medium.com/mindorks/custom-array-adapters-made-easy-b6c4930560dd
It may seem like a lot now, but I have also just started with this, and you'll get the hang of it fast.

java creating an object in subclass

Having trouble creating an author object in the Book class.This is indeed Homework, I have came up with all the methods on my own and have been staring at this assignment for 2 hours now. any tips hints will be appreciated. I believe I am only allowed this one Author constructor with 3 parameters otherwise I would just have made an Author constructor with no arguments and the problem would be gone.
public class Author {
protected String name;
protected String email;
protected char gender;
public Author(String name, String email, char gender)
{
this.name = name;
this.email = email;
this.gender = gender;
}
public String getName()
{
return name;
}
public String getEmail()
{
return email;
}
public void setEmail(String email)
{
this.email = email;
}
public char getGener()
{
return gender;
}
public String toString()
{
return ( name + "(" + gender + ")#" + email);
}
}
public class Book extends Author{
private String name;
private Author author;
private double price;
private int qtyInStock = 0;
public Book(String name, Author author,Double price)
{
this.author = new author;
this.name = name;
this.price = price;
}
public Book(String name, Author author, double price, int qtyInStock)
{
this.name = name;
this.author = author;
this.price = price;
this.qtyInStock = qtyInStock;
}
public String getName()
{
return name;
}
public Author getAuthor()
{
return author;
}
public double getPrice()
{
return price;
}
public void setPrice(double price)
{
this.price = price;
}
public int getQtyInStock()
{
return qtyInStock;
}
public void setQtyInStock(int qtyInStock)
{
this.qtyInStock = qtyInStock;
}
public String toString()
{
return (name + " by " + author + "(" + super.gender + ")at" + super.email);
}
}
It should be this.author = author; without the new keyword.
You are assigning the Author object in the constructor, not creating new one.
By the way, Book inherits from Author which means it already has the Author functionality. You don't have to save it as member.
Seems strange that Book extends Author. A Book is not an Author.
I think what you want to do is create a Book object that has an Author, but you are already passing in an Author to your Book constructor, so what is the problem?
class Book {
public Book(String title, Author author) {
this.title = title;
this.author = author;
}
}
If you're wondering how to create the Author, just create it before you pass it to the Book.
Author author = new Author("bob", "bob#email.com", 'm');
Book book = new Book("some title", author);
Does that make sense?
You are inheriting Author in Book, inheritance is is a relationship, means Book is a Author which is not true in real world scenario , you need has a relation which makes sense , that Book has a Author.
So don't extend author in Book , keep a field of author in it as you have already did. Change you design.
There are multiple mistakes in your code:
as #Guy said, you need to assign the author with this.author = author, without the new keyword.
you are shadowing the name variable from the Author class by also including a variable with the same name in the Book class. Remove that variable and the getter and setter methods from the Book class.
You donĀ“t have a no parameter constructor, so you have to call the parent constructor in your Book class by calling super(name, email, gender);.
you should replace new author with author, also when you call the constructor of a sub Type, the Parent class's default constructor is invoked by default. so you need to specify a default constructor in your parent class, or to prevent this explicitly call your parametric constructor of parent class in the child class constructor .
Besides changing tothis.author = author.
You also need to add super(name, name, 'M'); to the two constructors of the Book class.
public class Book extends Author{
private String name;
//private final String email;
// private char gender;
private Author author;// = new Author(name,super.email,super.gender);
private double price;
private int qtyInStock = 0;
public Book(String name, Author author,double price)
{
//super();
this.author = author;// new Author(name,super.email,super.gender);
super.name = author.getName();
super.gender = author.getGender();
super.email = author.getEmail();
this.name = name;
this.price = price;
}
public Book(String name, Author author, double price, int qtyInStock)
{
this.author = author;
super.name = author.getName();
super.gender = author.getGender();
super.email = author.getEmail();
this.name = name;
this.price = price;
this.qtyInStock = qtyInStock;
}
public String getName()
{
return name;
}
public Author getAuthor()
{
return author;
}
public double getPrice()
{
return price;
}
public void setPrice(double price)
{
this.price = price;
}
public int getQtyInStock()
{
return qtyInStock;
}
public void setQtyInStock(int qtyInStock)
{
this.qtyInStock = qtyInStock;
}
public String toString()
{
return (super.name + " by " + this.name + "(" + super.gender + ")at" + super.email);
}
also added this to the author class
public Author()
{
}

Categories