project tree image in this link
I am developing a social media app
In the Firebase database,
There will be Users node,posts node,likes node and request type nodes
Users nodes contains fields which represents users details and it has a uid which is like a key
Under the posts node, there will be a postskey within it there will be the details of the posts like uid,profileimage,postimage, description,date,time,fullname
The uid in the posts node is the uid in the Users node
I successfully uploaded images into the firebase storage and its url would be in the postimage field within the child node
To retrieve the particular users posts and display it in the particular users profile I tried this code which I enclosed in the images
But the posts of the user doesn't shows and white blank activity only shows up
Can u guide me to achieve my expected result
I am not good in English
Sorry,if you cannot understand my question because of my poor English
within OnCreate ,
mAuth=FirebaseAuth.getInstance();
currentUserID=mAuth.getCurrentUser().getUid();
PostsRef=FirebaseDatabase.getInstance().getReference().child("Posts");
myPostsList=(RecyclerView)findViewById(R.id.my_all_posts_list);
myPostsList.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager=new LinearLayoutManager(this);
linearLayoutManager.setReverseLayout(true);
linearLayoutManager.setStackFromEnd(true);
myPostsList.setLayoutManager(linearLayoutManager);
DisplayMyAllPosts();
within Displaymyallposts method
private void DisplayMyAllPosts() {
Query myPostsQuery=PostsRef.orderByChild("uid").startAt(currentUserID).endAt(currentUserID+"\uf8ff");
FirebaseRecyclerOptions<Posts> options=new FirebaseRecyclerOptions.Builder<Posts>().setQuery(myPostsQuery,Posts.class).build();
FirebaseRecyclerAdapter<Posts,MyPostsViewHolder> firebaseRecyclerAdapter=new FirebaseRecyclerAdapter<Posts, MyPostsViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull MyPostsViewHolder holder, int position, #NonNull Posts model) {
holder.fullname.setText(model.getFullname());
holder.date.setText(model.getDate());
holder.time.setText(model.getTime());
holder.description.setText(model.getDescription());
Picasso.get().load(model.getProfileimage()).into(holder.profileimage);
Picasso.get().load(model.getPostimage()).into(holder.postImage);
}
#NonNull
#Override
public MyPostsViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view=LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.all_posts_layout,viewGroup,false);
MyPostsViewHolder viewHolder=new MyPostsViewHolder(view);
return viewHolder;
}
};
myPostsList.setAdapter(firebaseRecyclerAdapter);
}
public static class MyPostsViewHolder extends RecyclerView.ViewHolder{
TextView fullname,date,time,description;
CircleImageView profileimage;
ImageView postImage;
public MyPostsViewHolder(#NonNull View itemView) {
super(itemView);
fullname=itemView.findViewById(R.id.post_user_name);
date=itemView.findViewById(R.id.post_date);
time=itemView.findViewById(R.id.post_time);
description=itemView.findViewById(R.id.post_description);
profileimage=itemView.findViewById(R.id.post_profile_image);
postImage=itemView.findViewById(R.id.post_image);
}
}
The post is retrieved
it's because of my silly mistakes
I forgot to give startlistening
That's the reason for not been able to retrieve the post
But there is an another problem
Except the image all other fields are displaying
But not the image
The image is still blank
Related
I want to search data from firebase. whenever a user type anything in the searchview it will search the related data. For example if user input the name of company it should show data related to that company, OR if user input price it should show data related to that specific price. My Recyclerview is working fine. I'm getting data but it only search data according to company name.
Here is My Code
private void getData(String query) {
Query firebaseSearchQuery = myRef.orderByChild("companyName").startAt(query).endAt("\uf8ff");
FirebaseRecyclerOptions<Package> options = new FirebaseRecyclerOptions
.Builder<Package>().setQuery(firebaseSearchQuery, Package.class).build();
final FirebaseRecyclerAdapter<Package, PackagesViewHolder> firebaseRecyclerAdapter =
new FirebaseRecyclerAdapter<Package, PackagesViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull PackagesViewHolder packagesViewHolder, int i, #NonNull Package aPackage){
packagesViewHolder.setDetails(getApplicationContext(), packagesViewHolder, i, aPackage.getPackageName()/*, aPackage.getPackageType()*/, aPackage.getCompanyName(), aPackage.getData()
, aPackage.getOnNetMinutes(), aPackage.getOffNetMinutes(), aPackage.getSms()
, aPackage.getPrice(), aPackage.getValidity()
, aPackage.getSubscriptionCode(), aPackage.getUnsubCode()
, aPackage.getRemainingDataCode(), aPackage.getInfo()
/*, aPackage.getTermsAndConditions()*/);
}
#NonNull
#Override
public PackagesViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_layout, parent, false);
PackagesViewHolder packagesViewHolder = new PackagesViewHolder(view, SearchActivity.this);
return packagesViewHolder;
}
};
recyclerView.setAdapter(firebaseRecyclerAdapter);
firebaseRecyclerAdapter.startListening();
}
There is no built-in operator on Firebase to search across all properties of a node. If your app requires such functionality, you might want to consider using a different/additional database for that, such as using Algolia for the searches and Firebase for the realtime sync.
Alternatively, you can build your own search structure inside of Firebase, as I've shown in my answer here: How to query based on multiple conditions in Firebase?
Also see:
Google Firestore: Query on substring of a property value (text search)
How to query firebase for property with specific value inside all children
How to perform sql "LIKE" operation on firebase?
Angularfire: How to access an item by one of it's properties?
You need to add an extra attribute to the database for example:
price-name : "18 comp"
And then do :
Query firebaseQuery = myRef.orderByChild("price-name").startAt(query).endAt("\uf8ff");
There is no or clause in firebase Realtime Database. The above is an alternative to be able to achieve that.
I could get it right with Realtime Database, but I went over to Cloud FireStore and now I'm running into some problems. I want to display an image that is in Firestore via a download URL from Firestore. I'm using the FirestoreRecyclerAdapter, I want to populate an imageView in a RecyclerView.
I tried to do it the same way it worked in Realtime Database, but I get an error, but this time I get an error telling me NumberFormatException: For input string:
#Override
protected void onBindViewHolder(#NonNull NoteHolder holder, int p,
#NonNull promo_one_data promo_one) {
holder.produk_product.setText(promo_one.getProduct());
holder.produk_discription.setText(promo_one.getDiscription());
holder.produk_discription_two.setText(promo_one.getDiscription_two());
holder.produk_size.setText(promo_one.getSize());
holder.produk_product_two.setText(promo_one.getProduct_two());
holder.produk_price.setText(promo_one.getPrice());
holder.produk_department.setText(promo_one.getDepartment());
if ("1".equals(holder.produk_department.getText().toString())) {
holder.itemView.setBackgroundColor(Color.parseColor("#FFCDD2"));
} else if ("2".equals(holder.produk_department.getText().toString())) {
holder.itemView.setBackgroundColor(Color.parseColor("#FFA6AF"));
} else {
holder.itemView.setBackgroundColor(Color.WHITE);
}
holder.produk_image.setImageResource(Integer.parseInt(promo_one.getImage()));
Picasso.get().load(promo_one.getImage()).into(holder.produk_image);
}
#NonNull
#Override
public NoteHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_promo, parent, false);
return new NoteHolder(v);
}
How can I display an image in a recyclerView from Cloud Firestore. It shows me "java.lang.NumberFormatException: For input string:...(the URL here), which I could gather means the string is to long to convert into a int to fill the imageView. How do I do this, or is there a way around? Or even how do I shorten the URL, or maybe is there a way to do it and not use Picasso?
Your problem is this line :
holder.produk_image.setImageResource(Integer.parseInt(promo_one.getImage()));
you should not be trying to parse the URL of the image to an integer here, the next line using Picasso:
Picasso.get().load(promo_one.getImage()).into(holder.produk_image);
should handle the image loading for you.
Hello I am new to Firebase database. Currently I am developing a android application. I am looking for a help, Below is my Firabase Data Structure. Can anyonce please tell me how to retrive the data.
Requirement is I have to retrieve the all the companies. Upon selecting the a specific company, it has to fetch the corresponding company coordinates into polygon shape variable.
Please Help
Why not have a structure like:
companyName/info
Instead of
Firebase ID/Companyname/info
i.e use update or set instead of push
public class CompanyIds{
public List<Company> companies;
}
FirebaseDatabase.getInstance()
.getReference("parent node path of these ID's");
Now in FirebaseRecyclerAdapter what you can do is:-
#Override
protected void populateViewHolder(final MessagesHolder viewHolder, CompanyIds model, int position) {
Company = model.companies.get(0);
//Set data on your view from Company model
}
As your ID is having only one company then you get that only company from the first index.
Now after clicking on any item, you can easily get the details for a company like coordinates or anything else in the same way you set the data in the adapter. It won't be a problem.
public class Company{
List<String> Cordinates;
List<Employees> Employees;
//Define other fields
}
Basically I got the answer from repetitive hits and tries while working on the similar problem.
Look when you go for general approach of add addValueEventListner(), you get a snapshot of the database with respect to your root node. Thus on the first addValueListner() callback, get the reference of your child node and then addChildEventListner() on it. So here is what i suggest:
DatabaseReference databaseReference=FirebaseDatabase.getInstance().getReference();
databaseReference.addValueEventListner(new ValueEventListner(){
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot){
//here your snapshot is considered with respect to root. So you get the reference of child node now
datasnapshot.child("Bureau 507").getRef().addChildEventListner(new
ChildEventListner){
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s){
for(DataSnapshot data: dataSnapshot.getChildren()){
//Now you are at the subtree of Bureua 507. So now you get your data in the form of
key and values
}
//remaining callbacks
I am using firebase database for storing data and firebase recycler adapter for showing the data.
RecyclerView recyclerView;
static String SelectedCode;
DatabaseReference root;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_get_data);
Firebase.setAndroidContext(this);
recyclerView=(RecyclerView)findViewById(R.id.recycler);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
root = FirebaseDatabase.getInstance().getReference();
Query query = root.child("download").orderByChild("subjectCode");
FirebaseRecyclerAdapter<CourseStorage, GetData.MessageViewHolder> adapter = new FirebaseRecyclerAdapter<CourseStorage, GetData.MessageViewHolder>(
CourseStorage.class,
android.R.layout.two_line_list_item,
GetData.MessageViewHolder.class, query
) {
#Override
protected void populateViewHolder(MessageViewHolder viewHolder, final CourseStorage model, int position) {
viewHolder.textView.setText(model.getSubjectCode());
}
};
recyclerView.setAdapter(adapter);
}
public static class MessageViewHolder extends RecyclerView.ViewHolder{
TextView textView;
View mview;
public MessageViewHolder(View itemView) {
super(itemView);
textView=(TextView)itemView.findViewById(android.R.id.text1);
mview=itemView;
}
}
The getSubjectCode function in CourseStorage class is
public String getSubjectCode () {
return subjectCode;
}
My database is
I am getting output as
I dont want same subjectCode to be displayed twice. How can i achieve it?
There is no GROUP BY clause in the Firebase Database query language. As is quite often the case when using a NoSQL database, the solution is to store the data in the way your app wants to access it.
In your case, since you're showing a list of subject codes, I'd store a list of subject codes in the database (in addition to your current data). For example:
latestItemKeyPerSubjectCode
"COEG301": "-KM...38N"
"COEG341": "-KM...vd-"
...
The exact value that you store really depends on your needs. In this case I stored the key of the most recent item with that subject code, but you could also store the file name (if you'd like to display that in your app) or simply true if you have no need for a meaningful value.
If i had to send a request to get data within onBindViewHolder(), how can i update view after data comes back from server?
what I have now is that I cache the data along with row position, so that next time when user scrolls to that row, I can display info right away.
but there are 2 other issues I don't know how to solve.
I scroll the list to view item at position 10, 11 and 12. I decided to wait for data to come back. do i call notifyDataSetChanged() after? because onBindViewHolder already been called by the time data comes back and view would just remained empty, but I also don't think by calling notifyDataSetChanged() after each request would be a good idea.
I start to view the list at position 0 and keep scrolling to position 10. app sends out request to pull data for position 0 to 10. since the request at 0 is sent out first, more likely it would get back first or at least sooner than position 10, but by that time I'm already viewing the item at position 10. my view would start changing if all requests are back in order, so it would show data for position 0 then keep updating all the way to 10.
is it a bad practice to load data from server as recyclerview scrolls? but by doing this would save me a lot of time, and I guess for user too? because instead of sending all the requests ahead of time, user get to see partial data while other data are being loaded in the background.
Thanks!!!
EDITED
public class TestAdapter extends RecyclerView.Adapter<TestAdapter.ViewHolder> {
private Context ctx;
private ArrayList<Photo> alPhotos = new ArrayList<>();
private HashMap<String, Drawable> hmImages = new HashMap<>();
public TestAdapter(Context ctx, ArrayList<Photo> alPhotos) {
this.ctx = ctx;
this.alPhotos = alPhotos;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_photo_brief, parent, false));
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Photo photo = alPhotos.get(position);
loadRemoteImage(photo.IMG, holder.ivThumb, true);
holder.tvEmail.setText(photo.EMAIL);
}
#Override
public int getItemCount() {
return alPhotos.size();
}
private void loadRemoteImage(final String imgUrl, final ImageView view, final boolean cache) {
if (hmImages.containsKey(imgUrl)) {
view.setImageDrawable(hmImages.get(imgUrl));
} else {
final WeakReference<ImageView> weakView = new WeakReference<>(view);
RequestManager.getManager().add(new Request<>(imgUrl, new DrawableParser(), new RequestCallback<Drawable>() {
#Override
public void onFinished(Request<Drawable> request, Response<Drawable> response) {
if (cache) hmImages.put(imgUrl, response.result);
ImageView view = weakView.get();
if (view != null) {
view.setImageDrawable(response.result);
}
}
#Override
public void onError(Request<Drawable> request, Response<Drawable> response) {
}
#Override
public void onTimeout(Request<Drawable> request, Response<Drawable> response) {
}
})
);
}
}
public class ViewHolder extends RecyclerView.ViewHolder {
private ImageView ivThumb;
private TextView tvEmail;
public ViewHolder(View itemView) {
super(itemView);
findViews();
}
private void findViews() {
ivThumb = (ImageView) itemView.findViewById(R.id.ivThumb);
tvEmail = (TextView) itemView.findViewById(R.id.tvEmail);
}
}
}
It's a good idea to load data while scrolling, a lot of popular apps do that. I personally use WeakReference in this case. I store a weak reference to the view holder in my model when I start loading data. If the reference is still valid by the time I get the response then it makes sense to update the view. If there is no view holder in memory then it's already been recycled and I don't have to update anything anymore.
When onViewRecycled is called you can clear the weak reference and also consider cancelling the network request (depends on your needs).
Caching works perfect with this model, you just insert this logic before making a network request. Again, this depends on your needs, maybe you don't need caching at all, or maybe your data is rarely updated then it makes sense to always use cache until some event.
In my app I also use EventBus, it helps me with event handling, but it is absolutely fine to just use Android SDK and support library.
You can also add a ScrollListener if you need to differentiate the item behavior depending on whether user scrolls the list right now. E.g. in my app I animate the data if list loaded and user wasn't scrolling it (improves interaction with the user). When user scrolls I load data as is, because it will be too much motion on the screen if I animate data.