Where's The Best Place To Call Methods That Interact With My Database?

I'm creating an app that interacts with a Firestore database. As of now I have a singleton class, DatabaseManager that has all the methods relating to the Firestore database (i.e. get/post methods).

I have a User model called User that has properties such as name, email, photoURL, and some app-specific properties. Any user can edit their profile to update information from a view controller called EditProfileViewController.

Now my question is: is it best to call the DatabaseManager.shared.updateInfo(forUser: user) (where user is a User instance) from EditProfileViewController, User, or some other place?

Sorry if this is an obvious question, but there's going to be a lot of points in the app where I'll need similar logic so I wanted to know what's the best design. Also I'm sure this question has more to with MVC than it does Firebase/Swift.



A couple of thoughts:

  1. Rather than accessing the singleton directly with, DatabaseManager.shared.update(for:), I might instead have a property for the database manager, initialize/inject it with the DatabaseManager.shared, and have whatever needs to interact with the database use that reference, e.g., dataManager.update(for:). The goal would be to allow your unit tests to mock a database manager if and when necessary.

  2. I would not be inclined to have a view controller interact directly with the DatabaseManager. Many of us consider the view controller, which interacts directly with UIKit/AppKit objects, as part of the broader “V” of MVC/MVP/MVVM/whatever. We’d often extricate business logic (including interaction with the database manager) out of the view controller.

    I personally wouldn’t bury it under the User object, either. I’d put it in an extension of the database manager, and called from the view model, the presenter, or whatever you personally want to call that object with the business logic.