0

As a beginner in Android and Firebase I mostly need an opinion and not code. Let me describe the situation and then I have 2 questions.

I am creating an application to store information about "paintings" and I want the user to be able to perform a search for a painting based on some colours they choose.

My database has a couple of nodes and the ones in question are:

Colours: where all the colours are stored. Every entry is in the form of UID->"Name":"Blue"

ColoursToPaintings: where every colour-UID has under it, a Painting object.

Paintings: where all the Paintings are stored. Each painting has a name, photourl(that leads to firebase storage), array with all the colours and other information.

They way I do it is(flow):

The application starts and the user can select colours that are loaded in the app from Firebase colours node (about 1000 colours). They search for eg. 5 colours.

I perform a for loop to create dynamically references to ColoursToPaintings so I can fetch all the Painting UIDs under these nodes (2000) paintings.

Then I perform another loop in these 2000 Painting UIDs to create references to the Paintings node so I can fetch the actual Paintings with all the information.

All these paintings are shown in a recyclerView list and photos (the photos are loaded with Glide to achieve lazy loading).

Question 1: Is the above approach the right one? Is there another way I should design the database / app?

So far, though the above approach seems to be working as expected, if I select many colours that produce many results, I get the issue of "skipped 40 frames maybe there is too much work on the main thread". Which leads in the Question 2.

Question 2: It is supposed that everything done with Firebase, is done in a separate thread(is it true?). Shouldn't all the work I do to be considered as a "background" task? I even tried to create separate AsyncTasks but still I get skipped frames.

Regarding the Question 2. Could the skipped frames be caused because every time a Painting is fetched by from the database, I add it to an ArrayList and then I περφορμ notifyDataSetChanged() on the adapter. Could notifyDataSetChanged() be expensive and cause the issue?

Thanks in advance.

user2399432
  • 738
  • 1
  • 9
  • 17

2 Answers2

1

This answer by Frank van Puffelen eloquently answers your second question. All Firebase actions happen outside of the main thread, hence, it's less likely that Firebase is causing the skipping of the frames.

Since you mentioned Glide, I'd like to add that Glide actions are also performed on separate threads.

Having said that, the following actions are the ones that are computationally expensive :-

  • Looping
  • Layout drawing ( specially for multiple layouts of a RecyclerView )
  • Changing the data set for the Recyclerview
  • Displaying pictures

I think you should reconsider how you implement the above. For example, you might consider simplifying the layout for each entry in the RecyclerView by reducing the depth of the view hierarchy.

Also, why don't you use notifyItemInserted(position) instead of notifyDataSetChanged()?

Community
  • 1
  • 1
Rohan Stark
  • 2,346
  • 9
  • 16
  • Thanks for the comments Rohan! – user2399432 May 19 '17 at 08:26
  • You're welcome! Were you successful in solving the problem? I might have a few useful modifications for the Firebase structure that you mentioned, and I could make an edit to my answer if your problem still persists. – Rohan Stark May 19 '17 at 08:50
  • I just posted a "solution" that I settled for.. I am not expert programmer so I will not be able to tell what is best or what is not. I used what you mentioned as "notifyItemInserted(position)" I hoe I did it on the right way! – user2399432 May 19 '17 at 09:09
0

So this is the answer to MY specific question and it does not mean that is the correct approach.. it is just happens to fit my needs on the current situation.. and therefore I settled for..

After trying a lot and several things I ended up that maybe it was MY fault since the beginning.

It seems like the skipped frames were caused because I was putting "heavy" workload on the RecyclerViewList as I was trying to scroll fast while the list was still getting populated, and not because the app was trying to process the data or the "complex" calculations.

I "tackled" the issue with 2 ways: 1) I implemented a loading ProgressBar so the user cannot interact with the list while is getting populated.

2) I also enabled offline data. Though this does not "solve" the issue, it helps to reduce the chances of the issue happening. (I needed offline data anyway)

In other words I think the main trick was to add a ProgressBar and prevent user to interact with the UI.

I might update the answer if I have more details later.

user2399432
  • 738
  • 1
  • 9
  • 17