So below are the database of my cloud firestore. That DatePosted shows 2nd December, 2019 at 8.19 pm UTC +8. According to the code I used and I run my app, it shows an unreadable number. Is it correct on how I retrieve the data from cloud firebase? If its wrong, how do I retrieve that timestamp and make it readable?
ForumAdapter.java
public class ForumAdapter extends FirestoreRecyclerAdapter<Forum,ForumAdapter.ForumHolder> {
private OnItemClickListener listener;
public ForumAdapter(FirestoreRecyclerOptions<Forum> options) {
super(options);
}
#Override
public void onBindViewHolder(ForumHolder forumHolder, int i, Forum forum) {
forumHolder.textViewTitle.setText(forum.getTitle());
forumHolder.textViewDescription.setText(forum.getDescription());
forumHolder.timeStamp.setText(forum.getDatePosted().toString());
}
#NonNull
#Override
public ForumHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
android.view.View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardviewforumtitle,parent,false);
return new ForumHolder(v);
}
class ForumHolder extends RecyclerView.ViewHolder{
TextView textViewTitle;
TextView textViewDescription;
TextView timeStamp;
public ForumHolder(View itemView) {
super(itemView);
textViewTitle = itemView.findViewById(R.id.tvTitle);
textViewDescription = itemView.findViewById(R.id.tvDescription);
timeStamp = itemView.findViewById(R.id.tvTimestamp);
textViewTitle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int position = getAdapterPosition();
// NO_POSITION to prevent app crash when click -1 index
if(position != RecyclerView.NO_POSITION && listener !=null ){
listener.onItemClick(getSnapshots().getSnapshot(position),position);
}
}
});
}
}
public interface OnItemClickListener{
void onItemClick(DocumentSnapshot documentSnapshot, int position);
}
public void setOnItemClickListener(OnItemClickListener listener){
this.listener = listener;
}
#Override
public int getItemCount() {
return super.getItemCount();
}
}
Forum.java
public class Forum {
private String Title;
private String Description;
private String User;
private com.google.firebase.Timestamp DatePosted;
public Forum() {
}
public Forum(String title, String description, Timestamp datePosted,String user) {
Title = title;
Description = description;
DatePosted = datePosted;
User = user;
}
public String getUser() {
return User;
}
public void setUser(String user) {
User = user;
}
public String getTitle() {
return Title;
}
public void setTitle(String title) {
Title = title;
}
public String getDescription() {
return Description;
}
public void setDescription(String description) {
Description = description;
}
public Timestamp getDatePosted() {
return DatePosted;
}
public void setDatePosted(Timestamp datePosted) {
DatePosted = datePosted;
}
}
When you query a document with a timestamp field, you will get a Timestamp object back. If you'd rather have a Date object, you can use its toDate method.
You will need to write some code to format this for display. This is a very common task for mobile and web apps.
Related
In my Android application, I am using RecyclerView with CardView. The contents of the RecyclerView are fetched from Firebase Realtime Database. For that I have used FirebaseRecyclerAdapter from FirebaseUI. The entries in the database correspond to POJO of class Bus.
public class Bus {
private String source;
private String destination;
private long available;
private String date;
private long fare;
Bus() {
}
Bus(String source,String destination,long available,String date,long fare) {
this.source = source;
this.destination = destination;
this.available = available;
this.date = date;
this.fare = fare;
}
public long getAvailable() {
return available;
}
public long getFare() {
return fare;
}
public String getDate() {
return date;
}
public String getDestination() {
return destination;
}
public String getSource() {
return source;
}
public void setAvailable(long available) {
this.available = available;
}
public void setDate(String date) {
this.date = date;
}
public void setDestination(String destination) {
this.destination = destination;
}
public void setFare(long fare) {
this.fare = fare;
}
public void setSource(String source) {
this.source = source;
}
}
In an activity, I accept the source, destination and date from the user. My intention is to display only the relevant data in the RecyclerView. This is my FirebaseRecyclerAdapter code:
FirebaseRecyclerAdapter<Bus,BusViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Bus,BusViewHolder>(Bus.class,R.layout.bus_card,BusViewHolder.class,mDatabase) {
#Override
protected void populateViewHolder(BusViewHolder viewHolder,Bus model,int position) {
if(model.getSource().equals(source) && model.getDestination().equals(destination) && model.getDate().equals(date)) // This is the criteria for displaying the card
{
viewHolder.setSource(model.getSource());
viewHolder.setDestination(model.getDestination());
viewHolder.setAvailable(model.getAvailable());
viewHolder.setDate(model.getDate());
viewHolder.setFare(model.getFare());
}
}
};
recyclerView.setAdapter(firebaseRecyclerAdapter);
Here is my ViewHolder:
public static class BusViewHolder extends RecyclerView.ViewHolder {
View mView;
public BusViewHolder(View itemView) {
super(itemView);
mView = itemView;
}
public void setSource(String source) {
TextView src = mView.findViewById(R.id.source);
src.setText("Source " + source);
}
public void setDestination(String destination) {
TextView dest = mView.findViewById(R.id.destination);
dest.setText("Destination " + destination);
}
public void setDate(String date) {
TextView dte = mView.findViewById(R.id.date);
dte.setText("Date " + date);
}
public void setAvailable(long available) {
TextView avail = mView.findViewById(R.id.available);
avail.setText("Available Seats " + Long.toString(available));
}
public void setFare(long fare) {
TextView fre = mView.findViewById(R.id.fare);
fre.setText("Fare " + Long.toString(fare));
}
}
The problem with this approach is that it displays the relevant cards, however there are empty cards for data which does not satisfy the condition. Is it possible to selectively retrieve data into the FirebaseRecyclerAdapter? Currently, the total number of cards created in the RecyclerView is equal to the total entries in the database.
I used query object to retrieve selectively from the Realtime Database. As query doesn't support multiple orderby clauses, I had to add an additional field in my node. This is the updated firebaserecycleradapter
query = mDatabase.orderByChild("sourcedestinationdate").equalTo(source+destination+date);
FirebaseRecyclerAdapter<Bus,BusViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Bus,BusViewHolder>(Bus.class,R.layout.bus_card,BusViewHolder.class,query) {
#Override
protected void populateViewHolder(BusViewHolder viewHolder,Bus model,int position) {
viewHolder.setSource(model.getSource());
viewHolder.setDestination(model.getDestination());
viewHolder.setAvailable(model.getAvailable());
viewHolder.setDate(model.getDate());
viewHolder.setFare(model.getFare());
}
};
recyclerView.setAdapter(firebaseRecyclerAdapter);
Note that the last parameter in FirebaseRecyclerAdapter is query.
I have the same code for another database and it works just fine, I have no Idea why it's not working here,
the onCreateViewHolder does not even get called.
(Appearently Stacks Overflow wants me to add more details to compensate for too much code so here's some unuseful Text , Text, Text , TEXT).
public class Course extends AppCompatActivity {
private RecyclerView mLocationView;
private DatabaseReference mLocation;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_course);
mLocation = FirebaseDatabase.getInstance().getReference("FINISHEDCOURSES");
mLocation.keepSynced(true);
mLocationView = (RecyclerView) findViewById(R.id.my_recycler_view);
mLocationView.setHasFixedSize(true);
mLocationView.setLayoutManager(new LinearLayoutManager(this));
}
#Override
protected void onStart() {
super.onStart();
FirebaseRecyclerOptions<Courses> options = new FirebaseRecyclerOptions.Builder<Courses>().setQuery(mLocation, Courses.class).build();
FirebaseRecyclerAdapter<Courses, CourseViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Courses, CourseViewHolder>
(options) {
#Override
protected void onBindViewHolder(#NonNull CourseViewHolder holder, int position, #NonNull Courses model) {
holder.setText(model.getDate(), model.getDistance(), model.getDriver(), model.getPrice());
}
#NonNull
#Override
public CourseViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.courses_rows, parent, false);
return new CourseViewHolder(view);
}
};
mLocationView.setAdapter(firebaseRecyclerAdapter);
firebaseRecyclerAdapter.startListening();
}
public static class CourseViewHolder extends RecyclerView.ViewHolder{
View mView;
public CourseViewHolder(View itemView){
super(itemView);
mView = itemView;
}
public void setText(String Date, String start, String end, String price){
TextView dateText = mView.findViewById(R.id.dateText);
TextView startText = mView.findViewById(R.id.depart_text);
TextView endText = mView.findViewById(R.id.end_text);
TextView priceText = mView.findViewById(R.id.price);
dateText.setText(Date);
startText.setText(start);
endText.setText(end);
priceText.setText(price);
}
}
The Courses Class
public class Courses {
private String driver, date, distance, preWaitTime, price, waitTime, client;
public Courses() {
}
public Courses(String driver, String date, String distance, String preWaitTime, String price, String waitTime, String client) {
this.driver = driver;
this.date = date;
this.distance = distance;
this.preWaitTime = preWaitTime;
this.price = price;
this.waitTime = waitTime;
this.client = client;
}
public String getDriver() {
return driver;
}
public void setDriver(String driver) {
this.driver = driver;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getDistance() {
return distance;
}
public void setDistance(String distance) {
this.distance = distance;
}
public String getPreWaitTime() {
return preWaitTime;
}
public void setPreWaitTime(String preWaitTime) {
this.preWaitTime = preWaitTime;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getWaitTime() {
return waitTime;
}
public void setWaitTime(String waitTime) {
this.waitTime = waitTime;
}
public String getClient() {
return client;
}
public void setClient(String client) {
this.client = client;
}
}
Here's The Database Structure :
Sorry I should have commented but i do not have enough reputation to do so.
I cannot see anything similar to this in your code.
FirebaseRecyclerAdapter<Courses, CourseViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Courses, CourseViewHolder>(
Courses.class,
R.layout.Courses,// should be your layout name
CourseViewHolder.class,
mLocation
) {
#Override
protected void populateViewHolder(CourseViewHolder viewHolder, category model, final int position) {
viewHolder.setName(model.getName());
viewHolder.setImage(getApplicationContext(),model.getImage());
I have an online quiz app in Firebase.
If my phone is in English, the app works fine, but when it change into Turkish, Piccaso does not load image.Please help me I can not find a solution for over a week
In this case my phone is in English
In this cas my phone is in Turkish
private void loadCategories() {
adapter = new FirebaseRecyclerAdapter<Category, CategoryViewHolder>(Category.class,
R.layout.category_layout,
CategoryViewHolder.class,
categories) {
#Override
protected void populateViewHolder(CategoryViewHolder viewHolder, final Category model, int position) {
viewHolder.category_name.setText(model.getName());
Picasso.get().load(model.getImage()).into(viewHolder.category_image);
viewHolder.setItemClickListener(new ItemClickListener() {
#Override
public void onClick(View view, final int position, boolean isLongClick) {
{
Intent play = new Intent(getActivity(), StartActivity.class);
Common.categoryId = adapter.getRef(position).getKey();
Common.categoryName = model.getName();
startActivity(play);
}
}
});
}
};
adapter.notifyDataSetChanged();
listCategory.setAdapter(adapter);
}
View Holder
public class CategoryViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
View mV;
public TextView category_name;
public ImageView category_image,gradient2;
public Button btnPlay;
private ItemClickListener itemClickListener;
public CategoryViewHolder(View itemView) {
super(itemView);
mV = itemView;
category_image = (ImageView)itemView.findViewById(R.id.category_image);
category_name = (TextView)itemView.findViewById(R.id.category_name);
gradient2 = (ImageView)itemView.findViewById(R.id.gradient2);
btnPlay = (Button)itemView.findViewById(R.id.btn_play);
btnPlay.setTag(R.id.btn_play,itemView);
btnPlay.setOnClickListener(this);
itemView.setOnClickListener(this);
}
public void setItemClickListener(ItemClickListener itemClickListener) {
this.itemClickListener = itemClickListener;
}
#Override
public void onClick(View v) {
itemClickListener.onClick(v,getAdapterPosition(),false);
}
}
Catgeory Model.java
public class Category {
private String Name;
private String Image;
private String Button;
public Category() {
}
public Category(String name, String image, String button) {
this.Name = name;
this.Image = image;
this.Button = button;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public String getImage() {
return Image;
}
public void setImage(String image) {
Image = image;
}
public String getButton() {
return Button;
}
public void setButton(String button) {
Button = button;
}
}
I find solution.I changed catgegory model and firabse json file.Maybe in category model Name And İmage translated into Turkish when changed phone language.
you model should be the same firebase json file. I changed model and jason file then app works fine.
Json File
"Category" : {
"01" : {
"ad" : "Azərbaycan",
"sekil" : "https://avatanplus.com/files/resources/mid/5969ff2ae80a415d460cbfc6.jpg"
},
"02" : {
"ad" : "Türkiyə",
"sekil" : "https://img00.deviantart.net/6f00/i/2012/238/9/0/turkey_flag_grunge_hd_2_0_by_syndikata_np-d5che5q.jpg"
},
"03" : {
"ad" : "Viner",
"sekil" : "https://img.milli.az/2017/12/08/606172.jpg"
}
Category Model
public class Category {
private String ad;
private String sekil;
private String Button;
public Category() {
}
public Category(String ad, String sekil, String button) {
this.ad = ad;
this.sekil = sekil;
Button = button;
}
public String getAd() {
return ad;
}
public void setAd(String ad) {
this.ad = ad;
}
public String getSekil() {
return sekil;
}
public void setSekil(String sekil) {
this.sekil = sekil;
}
public String getButton() {
return Button;
}
public void setButton(String button) {
Button = button;
}
}
I find solution.I changed catgegory model and firabse json file.Maybe in category model Name And İmage translated into Turkish when changed phone language.
everyone.
Hello. I’ve created android application. I am retrieving data from real-time database and also using recycle view + view holder. But when I go to another activity and then go back - my list oh view holder items was reset. How I can save state view holder and restore them?
I looked at various topics on the site, but not one answer did not help me.
My Pojo Class
public class Post {
private String post_id;
private String post_title;
private long post_date;
private long post_desc;
public Post(String post_id, String post_title, long post_date, String post_desc) {
this.post_id = post_id;
this.post_title = post_title;
this.comments_count = comments_count;
this.post_date = post_date;
this.post_desc = post_desc;
}
public void setPost_id(String post_id) {
this.post_id = post_id;
}
public String getPost_title() {
return post_title;
}
public void setPost_title(String post_title) {
this.post_title = post_title;
}
public String getPost_date() {
String month = new java.text.SimpleDateFormat("MM").
format(new java.util.Date(post_date * 1000));
int monthnumber = Integer.parseInt(month);
String value = new java.text.SimpleDateFormat("dd ").
format(new java.util.Date(post_date * 1000));
value +=MonthName[monthnumber-1];
value+= new java.text.SimpleDateFormat(" HH:mm").
format(new java.util.Date(post_date * 1000));
return value;
}
public void setPost_date(long post_date) {
this.post_date = post_date;
}
public String getPost_desc() {
return post_desc;
}
public void setPost_desc(String post_desc) {
this.post_desc = post_desc;
}}
ViewHolderClass
public static class PostViewHolder extends RecyclerView.ViewHolder {
public PostViewHolder(View itemView) {
super(itemView); }
public void setTitle(String title) {
titleViewPost.setText(title);
}
public void setDate(String date) {
dateViewPost.setText(date);
}
public void setDesc(String desc) {
descViewPost.setText(desc);
}}}
FirebaseRecyleAdapter
firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Post, PostViewHolder >(
Post.class,
R.layout.post_row,
PostViewHolder.class,
mDatabase
) {#Override
protected void populateViewHolder(final PostViewHolder viewHolder,
Post model, final int position) {
viewHolder.mCommentButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent commentActivity = new Intent(MainActivity.this, CommentActivity.class);
commentActivity.putExtra("post_id", post_key);
if(mUserId != null) {
commentActivity.putExtra("user_id", mUserId);
}
startActivity(commentActivity);
}
});
As I understand, the whole problem is that my adapter is reused and I can not return to that position in the tape - where I was before.
Its my app.https://play.google.com/store/apps/details?id=dev.arounda.chesnock
I want fix thiw trouble for this application
Try to call firebaseRecyclerAdapter.startListening(); in onCreate() instead of onStart and firebaseRecyclerAdapter.stopListening(); in onDestroy() instead of onStop()
I have 2 applications(different package names) which use one Firebase database. One app has to write access to the database and another have read access to the database.in my second application, i use recyclerview to retrieve data which is stored by 1st App.
for this I use below code:
FirebaseOptions options = new FirebaseOptions.Builder()
.setApplicationId("1:567....259c8f58311") // Required for Analytics.
.setApiKey("AIzaSyA9BRxl......hE03y5qD-c") // Required for Auth.
.setDatabaseUrl("https://mycity-3a561.firebaseio.com/") // Required for RTDB.
.build();
FirebaseApp.initializeApp(this /* Context */, options, "MyCity");
// Retrieve my other app.
FirebaseApp app = FirebaseApp.getInstance("MyCity");
// Get the database for the other app.
FirebaseDatabase secondaryDatabase = FirebaseDatabase.getInstance(app);
DatabaseReference data = secondaryDatabase.getInstance().getReference();
data.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot ds : snapshot.getChildren()) {
for (DataSnapshot dSnapshot : ds.getChildren()) {
WaterClass waterClass = dSnapshot.getValue(WaterClass.class);
Log.d("Show", waterClass.getName() == null ? "" : waterClass.getName());
list.add(waterClass);
}
adapter = new WaterAdapter(ShowWaterDetails.this, list);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
progressDialog.dismiss();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
progressDialog.dismiss();
}
});
}
Adapter class
private class WaterAdapter extends RecyclerView.Adapter<WaterAdapter.ViewHolder> {
ShowWaterDetails showDetail;
List<WaterClass> listData;
public WaterAdapter(ShowWaterDetails showWaterDetails, List<WaterClass> list) {
this.showDetail = showWaterDetails;
this.listData = list;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.show_items, parent, false);
WaterAdapter.ViewHolder viewHolder = new WaterAdapter.ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(WaterAdapter.ViewHolder holder, int position) {
WaterClass AllDetails = listData.get(position);
holder.NameTextView.setText(AllDetails.getName());
holder.DetailTextView.setText(AllDetails.getDetail());
holder.DateTextView.setText(AllDetails.getDate());
holder.LocationTextView.setText(AllDetails.getLocation());
holder.TypeTextView.setText(AllDetails.getType());
Picasso.with(showDetail).load(AllDetails.getImgurl()).resize(120, 60).into(holder.ImageTextView);
}
#Override
public int getItemCount() {
return listData.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
public TextView NameTextView;
public TextView DetailTextView;
public TextView DateTextView;
public TextView LocationTextView;
public TextView TypeTextView;
public ImageView ImageTextView;
public ViewHolder(View itemView) {
super(itemView);
NameTextView = itemView.findViewById(R.id.ShowNameTextView);
DetailTextView = itemView.findViewById(R.id.ShowDetailTextView);
DateTextView = itemView.findViewById(R.id.ShowDateTextView);
LocationTextView = itemView.findViewById(R.id.ShowLocationTextView);
TypeTextView = itemView.findViewById(R.id.ShowTypeTextView);
ImageTextView = itemView.findViewById(R.id.ShowImageView);
}
}
}
}
POJO Class
class WaterClass {
private String id;
private String email;
private String name;
private String type;
private String detail;
private String location;
private String date;
private String imgurl;
public WaterClass(){
}
public WaterClass(String id, String currentUserString, String imageUrl, String nameString, String typeString, String detailString, String locationString, String dateString) {
this.id = id;
this.email = currentUserString;
this.name =nameString;
this.type = typeString;
this.detail = detailString;
this.location = locationString;
this.date = dateString;
this.imgurl = imageUrl;
}
public String getImgurl() {
return imgurl;
}
public void setImgurl(String imgurl) {
this.imgurl = imgurl;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDetail() {
return detail;
}
public void setDetail(String detail) {
this.detail = detail;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
}
:
there is no error but my recycler not showing anything
go to onStart() and start listening
#Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
and in your onStop
#Override
protected void onStop() {
super.onStop();
adapter.stopListening();
}
The FirebaseRecyclerAdapter uses a snapshot listener to monitor changes to the Firestore query. To begin listening for data, call the startListening() method. You may want to call this in your onStart() method. Make sure you have finished any authentication necessary to read the data before calling startListening() or your query will fail.
Be sure that the names of constant in the POJO match exatly the names
of your database structure in your firebase console !!
ps: do not post your api-keys or app-ids in your questions, keep them secret, and consider using firebaserecycleradapter if you are using firebase-database , it will be more easy to setup and to show values.
Your POJO is ok !
Found Solution!!
just change this part of a code
FirebaseApp.initializeApp(this /* Context */, options, "MyCity");
// Retrieve my other app.
FirebaseApp app = FirebaseApp.getInstance("MyCity");
TO
FirebaseApp.initializeApp(this);
// Retrieve my other app.
FirebaseApp app = FirebaseApp.getInstance("[DEFAULT]");