1

I'm trying to find a way around the integration of Google and Facebook login for an Android application using the Clean Architecture.

My application has 3 Android Studio modules :

  • presentation : contains the Interface Adapter layer of the Clean Architecture (Presenters), along with all my UI (Activity, Fragment, Custom Views) (part of the Framework and Driver layer)
  • domain : This is the Use Case layer of the Clean Architecture. It contains the business models, Use Cases, and repository interfaces
  • data : This contains all the Driver and Framework classes, the libraries (retrofit, databases, etc) and repository implementations

I would like to isolate the login specific SDKs in my data layer (which is a separate module in Android Studio).

The issue I have for this particular use case (Google login for example) is that the SDK need to talk directly to my Activity (presentation layer). Once I have built a specific object, I need to call startActivityForResult from an Activity, and I receive a callback in the onActivityResult method of my launching activity, containing the login informations.

These 2 things make an obligation to :

  • either keep the Google/Facebook SDK dependencies in the presentation layer. BUT this violates the clean architecture principle, I would like to keep these dependencies in my data layer
  • or add a call which will go through all my layers (presentation, domain and data) to give back the login informations from the onActivityResult method. BUT this means that I would modify my domain contract because of a particular login SDK

None of this seems OK. Do you know a proper way to handle this use case ?

  • Your names are throwing me off. Clean Architecture has an interface adapter layer that has presenters in it. But it doesn't have domain or data layers. Onion architecture doesn't fit all your names either, though it does have a domain. The closest fit is 3 tier which has presentation and data but not domain. Are you looking to follow one of these or are you making your own? – candied_orange Feb 26 '18 at 12:38
  • My names are confusing. Here is a clarification about my 3 differents modules : - presentation : it corresponds to the interface adapter layer - domain : it corresponds to the use case layer of the onion architecture - data : it corresponds to the first level of the onion architecture, where all the framework dependencies belong – Rafi Panoyan Feb 26 '18 at 12:43
  • If you want us to follow your post with Clean Architecture in mind please edit the post to use it's terms. Don't explain discrepancies away in a comment. – candied_orange Feb 26 '18 at 12:48
  • it's edited. If you need other clarifications to understand the architecture issue I'm facing, feel free to ask – Rafi Panoyan Feb 26 '18 at 12:51
1

If I understand you right, you're mapping your modules onto clean architecture like so:

( Data ( Presentation ( Domain ( ) ) ) )

enter image description here

That's fine. Names are a little different than I expected but it can work.

I would like to isolate the login specific SDKs in my data layer (which is a separate module in Android Studio).

That's a good instinct right there. Knowledge of which specific login SDK you are using should not be allowed to spread. Keep it in one place.

The issue I have for this particular use case (Google login for example) is that the SDK need to talk directly to my Activity (presentation layer). Once I have built a specific object, I need to call startActivityForResult from an Activity, and I receive a callback in the onActivityResult method of my launching activity, containing the login informations.

These 2 things make an obligation to :

either keep the Google/Facebook SDK dependencies in the presentation layer. BUT this violates the clean architecture principle, I would like to keep these dependencies in my data layer

Clean Architecture is not a principle but yes, this would be bad.

or add a call which will go through all my layers (presentation, domain and data) to give back the login informations from the onActivityResult method. BUT this means that I would modify my domain contract because of a particular login SDK

Remember it's knowledge of which specific SDK that we're using that we wish to isolate. The idea of logging in is definitely something that cuts through the layers. As you descend the layers knowledge about the details about the login should be being stripped away. So google's login SDK can live in your Data layer but Presentation should just be thinking of this as a login to present in some language/API that the SDK speaks. That is your Output Port here. Domain should be thinking of login without caring what language/API the SDK speaks.

So to me this seems ok. If you do it right.

  • These type of SDKs communicate according to the OAuth2 protocol. If I understand your (very complete) answer, the presenter can have an API to speak the OAuth2 language (i.e. getting a token to send to another server). The Domain then must carry this data, without knowing it's a token (not sure about that), and send it to my server through an interface. I think one flaw of my design is that my Domain layer can communicate directly to the Data layer (through an interface though) – Rafi Panoyan Feb 27 '18 at 10:06
  • @RafiPanoyan No you shouldn't be skipping layers. Communication from your domain to your data should go through presentation. When it goes through presentation details unique to the protocol can be added back. Also You seem to be missing a controller. Communication from your data to your domain should go in through a controller module. Here info unique to the particular login SDK is striped away and expertiese at talk to the domain input port is employed. This separates input and output. – candied_orange Feb 27 '18 at 10:17
  • @RafiPanoyan Would you be interested in an example? It's a button push implemented in a Clean Architecture. – candied_orange Feb 27 '18 at 10:21
  • "The Domain then must carry this data, without knowing it's a token" The domain shouldn't "statically" know about the protocol. It's OK to dynamically hold useful data. But I shouldn't be able to look at your source code for your domain and get any hint at all which particular login SDK protocol you are using. If those details aren't here you can swap out your presenter to support a different protocol without touching your domain code. – candied_orange Feb 27 '18 at 10:38
  • I'm interested in your example, thanks ! The thing is that even the name "token" for an attribute let us know which kind of protocol we are using. We could already tell that it's not a classic login with email and password but a OAuth type. Here, a classic login and an OAuth login are not swapable easily without touching the domain code – Rafi Panoyan Feb 27 '18 at 13:49

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.