/shoppingify-firebase

Legacy DevChallenges Shoppingify with Angular and Firebase (WIP)

Primary LanguageTypeScript

Shoppingify Firebase

This is a reworking of a legacy DevChallenges project I completed with React.

Built With

Thoughts

  • Firebase doesn't return observables. It returns promises. You can convert the response to an Observable with from. Use toSignal?
  • Angular Fire does a lot of the work for you.
  • Firebase uses IndexedDB to store a key to remember the logged-in user.
  • Cloud Firestore is schemaless.
  • If you want to delete documents in subcollections when deleting a parent document, you must do so manually.
  • Firebase doesn't return the whole object of newly saved objects.
  • Need to do a lot of planning and prototyping of data structure in Firebase, as you are billed by the number of reads and writes you perform.
  • You have to balance query efficiency, data consistency, data duplication, and scalability.
  • "Snippet" fields can be a useful way to limit reads, but you can run into syncing issues.
  • Queries find documents in a single collection only.
  • You can't retrieve a partial document.
  • You can't easily delete subcollections.
  • Queries are shallow.
  • Root-level collections are good for many-to-many relationships.
  • PrimeNG has some chart functionality so that is one reason I decided to use it instead of Angular Material.
  • PrimeNG menu components have limited vertical orientation options. It would be nice to have orientation available to all menus, but I believe animations would break if you try to use most menu components in a vertical position. See this Github discussion for the limitations of the TabMenu component.
  • MegaMenu, TieredMenu, and Dock can be used vertically.
  • Adding a tooltip to MenuItems in the TieredMenu component does not work? I looked in the source code and the TieredMenu component has the pTooltip directive.
  • You can't use a title attribute for a tooltip either. See this Github issue.
  • Object.keys does not work inside an Angular template.
  • Could use a sidepanel or a modal for the new item form.
  • Since I am using a dropdown for the category input and it is the last input of the form, it might not be a good idea to use a modal for the form.
  • Use a router-outlet for the cart and the new item form? An advantage of using router outlet would be always having a correct URL path.
  • The original DevChallenges design does not take into account mobile design. Having separate URL paths would help translate the design to mobile.
  • Used CSS layers to have a CSS reset without overwriting the PrimeNG component styles.
  • Passing a formData object as a payload to Firebase does not work. I changed to pass a plain object.
  • Could use nested document references for the category field. Since I always need that data, I don't think that would be a good idea. I need to look more into populating document references with Firebase, but it doesn't seem as easy as Mongoose with its populate function.
  • Firebase doesn't recommend saving arrays. I would want to save an array of items and a name for the shopping list object. In the prior app, past shopping lists are not allowed to be updated so the drawbacks of arrays really does not apply.
  • If I were to allow lists to be edited, I would need to change how I am saving the list items. Then a user can update the status of an item (purchased or not).
  • I included a simple bar chart to see the total amount of items needed from all lists.
  • I need to look into filtering items based on saved list date.
  • AngularFire documentation is quite poor. Issues have been filed, but not much has been done in years. Issues get closed and the documentation stays outdated. Even the official firebase website documentation seems outdated.
  • This issue about documentation opened in 2022 does not even seemed to have been looked at by a core maintainer. This issue makes it plain that Google is not treating AngularFire as a core library.
  • With PrimeNG buttons, you don't have to put content inside the button and can use an attribute to add button text. This is fine, but ESLint complains when buttons do not have content.
  • Create another service that calls the PrimeNG MessageService and import that verus importing MessageService directly into multiple components?
  • Splitter's minimum sizes array is not working. See this Github issue.
  • I used Splitter for the layouf of the Home component. I may convert to a grid. I could also look into using a DataView component.
  • Custom PrimeNG styling relies on using ng-deep. This could be a maintenance headache in the future if ng-deep is ever removed from Angular.

Continued Development

  • PrimeFlex? Using CDN temporarily -> if I keep it, I will install it properly.
  • TypeScript fixes
  • Tests
  • Replace getRawValue in the register and login submit functions?
  • Lists need a status -> active or completed.
  • Categories need to created first on Firebase. You cannot submit the item form without a category.

Useful Resources

  • JSON formatter
  • Picsum
  • Blog - CSS Reset
  • MDN Docs - IndexedDB API
  • YouTube - Angular Firebase Authentication - Implement Auth in Minutes
  • YouTube - How to Connect Firebase to Angular Project - Do It Right
  • Firebase Docs - data model
  • YouTube - Model Relational Data in Firestore NoSQL
  • YouTube - Maps, Arrays and Subcollections, Oh My! | Get to know Cloud Firestore #4
  • Stack Overflow - getting timestamp creation date from firebase doc where it is not saved manuall
  • Blog - this is how we write firebase cloud functions
  • YouTube - Angular 17 Crud Operation with Firebase
  • Medium - angular reactive form using primeng and its validation
  • BezKoder - angular 16 firebase crud
  • Blog - ionic angular tutorial firebase realtime crud mobile app
  • YouTube - Basic To-Do App using AngularFire v17 Compat
  • Firebase Docs - enable offline
  • Github Docs - angularfire version 7 upgrade
  • Github - angular fire crud
  • Medium - angular reactive form using primeng and its validation
  • Forum - should a button go inside or outside a fieldset
  • Github - Menu & TrieredMenu - add option to inject custom icons by template or model #13496
  • Reddit - ngdeep alternatives
  • Stack Overflow - access key and value of object using ngfor
  • Stack Overflow - iterate over object in angular
  • Stack Overflow - how to iterate over object in angular 17 with new for
  • Stack Overflow - typescript looping through a dictionary
  • Stack Overflow - display map content in angular 4
  • Dev.to - firebase v9 firestore adddoc and setdoc method examples
  • YouTube - Signals Unleashed: The Full Guide
  • Github - Angular Signals
  • YouTube - How I imported a local JSON into a Firestore collection.
  • Stack Overflow - save array of object to firebase without getting 0 1 2 as key
  • Stack Overflow - force routerlink to refresh component
  • Github - angularfire route guards
  • Dev.to - angular 12 with firebase 9
  • Stack Overflow - convert timestamp to date using angular 2 pipes