There're 3 fragments
- AuthFragment - is responsible for the authentication of the user. The authenticated user is stored in the
AuthUserclass. The 'AuthUserclass is passed to theHomeFragment` via safe args. - HomeFragment - is responsible for displaying some widgets, whatever, allows to logout (that's why it needs the
AuthUser- the app gets back toAuthFragmenton logout) and to go to theProfileFragment. TheProfileFragmentdoesn't need to know anything about authentication, that's why theHomeFragmentcreates aHomeUserclass which contains the profile information and other things. TheHomeUserclass is passed to theProfileFragmentvia safe args - ProfileFragment - displays the
HomeUserdata and allows to get back to theHomeFragment
In short, the navigation graph looks like this:
- AuthFragment --(AuthUser)--> HomeFragment
- HomeFragment --> AuthFragment
- HomeFragment --(HomeUser)--> ProfileFragment
- ProfileFragment <--(What here???)-- HomeFragment
The AuthFragment uses the AuthViewModel and the AuthRepository to handle the firebase authentication, but it's not in the scope of this question, so I won't get deeper into it.
Here's the thing, what should I use:
- safe args - the
HomeFragmentwould take theAuthUserand theHomeUseras arguments, and theAuthUserwould also be passed as an argument to theProfileFragmentbecause theHomeFragmentneeds to have theAuthUservalid, so to get back to theHomeFragmentwith a validAuthUsertheProfileFragmenthas to have the validAuthUser.
//AuthFragment to HomeFragment, HomeUser is null
AuthUser authUser = getAuthUser();
var action = AuthFragmentDirections.authToHome(authUser);
NavHostFragment.findNavController(AuthFragment.this).navigate(action);
//HomeFragment to ProfileFragment
AuthUser authUser = getAuthUser();
HomeUser homeUser = getHomeUser();
var action = AuthFragmentDirections.homeToProfile(authUser, homeUser);
NavHostFragment.findNavController(HomeFragment.this).navigate(action);
//ProfileFragmentto HomeFragment
AuthUser authUser = getAuthUser();
HomeUser homeUser = getHomeUser();
var action = AuthFragmentDirections.profileToHome(authUser, homeUser);
NavHostFragment.findNavController(ProfileFragment.this).navigate(action);
//getting the authUser from arguments
authUser = HomeFragmentArgs.fromBundle(getArguments()).getAuthUser();
It sounds confusing, I know... that's why I thought of the HomeViewModel class that would contain the AuthUser and the HomeUser, so let's get into what I thought of
- ViewModel to save the
AuthUseror/and theHomeUser- I've got 2 ideas.
- The
AuthViewModelwill be also used in theHomeFragment, which is not ideal, becauseAuthViewModelcontains methods strictly for authorization - Create a
HomeViewModelthat will have theAuthUser
public class HomeViewModel extends ViewModel {
public AuthUser authUser;
public HomeUser homeUser;
}
and in the HomeFragment
authUser = HomeScreenArgs.fromBundle(getArguments()).getAuthUser();
homeViewModel = new ViewModelProvider(this).get(HomeViewModel.class);
homeViewModel.authUser = authUser;
My question is, which method is more correct?
- It doesn't matter if the
ProfileFragmenthas access to theAuthUserand I can just pass it all around using safe args - I should use the
AuthViewModel, which has authentication methods, in theHomeFragment. - I should use a combination of safe args and a ViewModel to pass the
AuthUserto theHomeFragmentand save it inside a ViewModel