Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Code Review 1 - PolyEvent #129

@zyuiop

Description

@zyuiop

This is a review of the entire codebase at commit cd8465c.

Of course, we don't expect you to change all of your code (some parts of the review can be subjective), what’s important is that you understand why better alternatives may exist.

Please ask us if you have any question about the code review, whether it is by writing a comment below or by sending us an email.

Important : if you try to fix these, don't break your app. We prefer that the app works even if you don't manage to fix anything. It may be too hard to rework some of the issues below.

General Remarks

Code Structure

  • The package structure is relatively well organized
  • You do not use an abstraction for login/logout/user management: Firebase is directly used in your views. You should really use an abstraction layer between Firebase and your views. You will find more details in the detailed code review below.
  • Your abstraction for the Database seems hardly manageable in the long term because you only use one interface for all your database operations. You should split it and have one interface for each data type you are managing.
  • We really think you should use Dependency Injection to make your life easier. See for example the Hilt framework.

Code Style

Globally, your code style is consistent. In some files however we saw some variations: single line comments had no space (i.e. you did //comment instead of // comment), no spaces around a ==... We suggest you use the automatic code reformatting from Android Studio before commiting code.

You should also have a look at the results of the linter, which can be found at Analyze > Inspect Code in Android Studio. In general, most warnings are relevant, but if you think they are not you can choose to ignore them using @SuppressWarning with a comment, or disable some of the checks entirely in your project settings.

Finally, you use Kotlin, which supports a nice syntax to access view elements from your code (instead of the good old but cumbersome findViewById). See a quick intro here: https://medium.com/androiddevelopers/use-view-binding-to-replace-findviewbyid-c83942471fc. You're free to not use this :P

By File

Only files for which we have a comment are referenced here.

Packageadapter

EventItemAdapter

  • (Nit) Small issue at line 39: use a resource string with placeholder instead of a concatenation

ItemAdapter

  • In general, please try to avoid pushing debug/incomplete code to master
  • You're probably still working on this, but it is not a good practice to query the database directly from the adapter. Your adapter should only receive a List (or a MutableLiveData) and handle displaying it to respect separation of concerns (as you did in the two other adapters).

Package database

Database

  • Line 9: mutableCurrentDatabase should probably be private
  • In general: we tend to prefer Dependency Injection (DI) to a static singleton like yours, but it seems to work so you don't have to switch to DI if you don't like it.

DatabaseInterface

  • (Important) You should have one database interface for each data-type, instead of one huge database interface that handles all data

    • This will also be usefull later when you will implement local data caching, since this will use a local database such as Room instead of a remote one such as Firebase

    • You may realize that it's too cumbersome to use your Database object for all these new database instances. DI is nice for that, we recommend using Hilt.

  • It is better to separate your database from your view using the Repository pattern, see here: https://developer.android.com/codelabs/kotlin-android-training-repository?index=..%2F..android-kotlin-fundamentals#5

  • You should use asynchronous methods to query your database, the abstraction used for getUserInformation(...) is nice (although the documentation for this method is incorrect)

FakeDatabase

  • At the end of the semester, when you no longer need "fake data" to showcase your views, make sure that the FakeDatabase is moved to androidTest since it's not good to have test code mixed with the production code.

FirestoreDatabaseProvider

  • Same remark as DatabaseInterface: this is too long, you should definitely have one firebase provider for each collection of data (users, items, events, ...)

Package database.observe

Very nice and clean abstraction, we had some trouble understanding its purpose as it seems to be equivalent to the features offered by LiveData, but it's very cool!

Package exceptions

InsufficientAmountException

  • You should add doc to describe when this exception is supposed to be thrown and how to handle it.

Package fragments

AdminHubFragment

  • Doc: line 19, the method newInstance doesn't exist

HomeFragment

  • Your usage of the LinearLayout seems very close to a RecyclerView. Why not use that instead?
  • (Nit) You have useless imports: before commiting, it's a good practice to reformat your code and optimize imports. It seems well respected in the project overall.

ListFragment

LoginFragment

  • Your fragment directly calls Firebase and Google Sign In. You should add an abstraction layer between your display and the backend. This abstraction layer should be generic enough to be replaced by a stub while testing, and maybe by other providers if you need that later.
  • Some variable names are not very transparent. Example: line 117, newValue2.
  • This class lacks documentation. Private methods are not obvious, a few lines of KDoc would help other developers from the team understand what your code does.

MapsFragment

  • PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION should be declared as const

MoreFragment

  • Doc: line 21, the method newInstance doesn't exist
  • Doc: it's unclear what this fragment does
  • Naming: (you already have a todo on that) ARG_PARAM{1,2} are unused and badly named

ProfileFragment

  • L25-27: "User that we can set manually for testing": you should really use dependency injection for that. Have a UserManager or UserRepository store the current user. Make it use Firebase in prod, and have a test implementation that uses an arbitrary user that you can set manually. Have all classes use this manager/repository instead of this field.
  • L47: similar remark here (and similar to login fragment): you should not use firebase code directly in your activity, use an abstraction layer as described before.

Package helper

GoogleMapHelper

  • Using a Context in an object is bad practice. Why use a singleton here? You should make it a class and simply store the instance in the fragment. You could also wrap the GoogleMap instance (use it as a constructor parameter and make it immutable)

HelperFunctions

  • (Nit) DateToLocalTime and LocalDateToTimeToDate: in Java/Kotlin, conventions require method names to start with a lowercase letter.

Package model

Your entities are well-thought and clean, good job!

Depot

  • Not an entity, should be in the database package and rewritten+named accordingly (InventoryRepositor?).

Package util

Converting database data from/to your own data format should be the role of the Database and/or Repository classes.

You could also create a new interface DocumentSerializable that would define a toDocument method to produce a hashmap. Reading from a map could be achieved with a similar fromDocument method (but your class would need an empty constructor and be mutable ; you can also use a static method in a companion object).

In our opinion, all the objects from this package contain features that should be implemented somewhere else. The implementation is however very clean.

FirebaseUserAdapter

  • Converting to/from your internal user class could be a very nice job for the UserManager we suggested before.

Tests

Your tests look very good, kudos for that

Conclusion

Your code is very good overall, you have nice abstractions and lots of efforts put in. The documentation and maning are mostly clear and understable, the codestyle is mostly consistent. The app design is very cool. Keep up the good work!

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions