How do i connect the firebase Firestore to my swift app - swift

I have tried many different resources online but they all seem to use app delegate files and I get TOTALLY confused.
All I want to be able to do is read and write from the cloud firestore to my swift app
I have installed firebase and the firestore via the package manager and it can't seem to find the Firestore Manager
import SwiftUI
import Firebase
#main
struct RecipyApp: App{
#UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
#StateObject var firestoreManager = FirestoreManager()
var body: some Scene{
let viewModel = AppViewModel()
WindowGroup{
ContentView()
.environmentObject(viewModel)
.environmentObject(firestoreManager)
}
}
}
class AppDelegate: NSObject, UIApplicationDelegate{
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
FirebaseApp.configure()
return true
}
}
MY CODE.
What can I do to fix my problem?
Many thanks

Solution 1:
Delete The Excess Package And Run The App
Solution 2:
Go To Xcode Preference > Location, Delete Derived Data

Related

How to add code to AppDelegate using SwiftUI Life Cycle

I'm following Google's tutorial on how to integrate AdMob ads into my app. In the tutorial, they put some code into the App Delegate. I've only ever used the SwiftUI life cycle for apps, so I'm not even sure what the App Delegate is. However, the issue is that in the tutorial, they instruct to put this code in the App Delegate file:
[[GADMobileAds sharedInstance] startWithCompletionHandler:nil];
I'm trying to put this code into the init() of my app (aka the SwiftUI version of putting it into my App Delegate). However, as this doesn't seem to be Swift code, I can't use that line of code without receiving errors. What should I do to insert this code into my app init()?
Following this tutorial at around 3:10 into the video.
The init might be too early, try in app delegate as follows
import GoogleMobileAds
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
GADMobileAds.sharedInstance().start(completionHandler: nil) // << here !!
return true
}
}
#main
struct YourApp: App {
#UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}

Error with appDelegate while testing firebase based app

Im trying to do some snapshot tests on my firebase based app.
I made some snapshot tests with 'LogInVC' it worked well because it has nothing in common with firebase but then, after LoginTests I've tried to test tableView that should be shown after successful login:
First I made "TestingAppDelegate" in test target:
import UIKit
#objc(TestingAppDelegate)
class TestingAppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
print(">> Launching with testing app delegate")
return true
}
To avoid the regular app delegate during testing I made a code in a file called "main" that tries to find a class named TestingAppDelegate made in "Testing" target and also deleted #main in regular AppDelegate.
import UIKit
let appDelegateClass: AnyClass =
NSClassFromString("TestingAppDelegate") ?? AppDelegate.self
UIApplicationMain(CommandLine.argc, CommandLine.unsafeArgv, nil,
NSStringFromClass(appDelegateClass))
This is how my test looks:
class UsersTests: XCTestCase {
var sut: AllUsersViewController!
override func setUp() {
sut = AllUsersViewController()
sut.loadViewIfNeeded()
}
override func tearDown() {
sut = nil
}
func testInitialLoginScreen(){
setUsers()
assertSnapshot(matching: sut, as: .image, record: true)
}
func setUsers(){
for number in 0...5{
let user = UserInfo(firstName: "Nikola", lastName: "Andr", username: "lol", pictureURL: nil, training: ["lol","mma"], uid: "\(number)", admin: false)
sut.users.append(user)
}
}
When I run tests this is error I get in "main" file that switches app delegates.
"The default FirebaseApp instance must be configured before the
default Authinstance can be initialized. One way to ensure this is to
call FirebaseApp.configure() in the App Delegate's
application(_:didFinishLaunchingWithOptions:) (or the #main
struct's initializer in SwiftUI)."
I've never tested firebase app before so I don't know that to do now. Any reference where to learn about how to test firebase apps will be helpful too.

How do you use Firebase within a custom class?

I went through the steps to set up Firebase on my app and it tested well. But when I created a custom swift class to make functions to manage the database, it crashes and says "failed to get default firdatabase instance. must call firapp.configure() before using firdatabase". I called configure() in the AppDelegate but it doesn't seem to be passing through to my custom class. Below is the error I get, my part of the AppDelegate where i called FirebaseApp.configure(), and the custom class. Thanks in advance.
DatabaseTestApp[7814:336288] *** Terminating app due to uncaught exception 'FIRAppNotConfigured', reason: 'Failed to get default FIRDatabase instance. Must call FIRApp.configure() before using FIRDatabase.'
import UIKit
import Firebase
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
FirebaseApp.configure()
return true
}
}
my custom class:
import Foundation
import UIKit
import FirebaseDatabase
class FirebaseClass
{
var ref:DatabaseReference?
init ()
{
ref = Database.database().reference()
}
}
Assuming you are creating some sort of class called FirebaseManager, do the following:
class FirebaseManager {
public static let instance = FirebaseManager()
private init(){
FirebaseApp.configure()
}
}

Access a viewController struct from appDelegate

I have a struct defined in my ViewController as follows:
struct Meme {
var topText : String
var bottomText : String
var originalImage : UIImage
var memedImage: UIImage
}
Now when I try to access the struct from appDelegate using the following code, I get an unresolved identifier error:
var memes = [Meme]()
can someone please explain why this is happening and how can i access the viewController struct from my appDelegate?
Thanks!
You can't access the properties of a class without having an instance of it.
In AppDeletegate file do this:
// create instance of your viewcontroller class
let viewController = ViewController()
// access the property
viewController.memes = [Meme]()
This is possible in another way to:
import UIKit
var memes = [Meme]()
class ViewController: UIViewController {
}
ok the memes are not exacly in the scope of UIViewController, but they are in the same file, like this they are global variable.
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
print(memes[0].bottomText)
return true
}
Wish you all the best.
Assuming the struct is defined inside your ViewController class like you said, you will need to access it using the namespace of the ViewController in the following way:
var memes = [MyViewController.Meme]()
I actually figured this out long back. Sorry for the delay in update. People with the same problem, please create a new swift file called "Meme.swift" and then write the meme struct inside that file. Your problem should be solved now. Thanks!

Am I doing this correctly? Swift 3 xcode loading data from firebase

The way I currently load my data is in the viewWillAppear on their specific view controllers. My question is should I load all the data on the Home/Main View Controller and pass the data that way? Or is the current way Im doing it better?
I know this is subjective, I'm loading ALOT of data.
Structure:
If you do not want the data to persist between app processes (when the app is closed the data is cleared), you can use Global Variables. When it comes to retrieving data, I suggest you to create a function in AppDelegate called retrieveFromFirebase(), containing every piece of code needed to retrieve data in your app, for all the UIViewControllers of your app. Then you should call it inside
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {}
Then, inside your function, you should assign the snapshot's value to the global variable declared earlier.
Example:
This is an example of how to setup AppDelegate.swift for this:
import UIKit
import CoreData
import Firebase
//declaration of the global variable
var username = String()
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
FIRApp.configure()
retrieveFromFirebase()
return true
}
func retrieveFromFirebase(){
// get the data from Firebase
let ref = FIRDatabase.database().reference()
ref.child("username").observe(FIRDataEventType.value, with: { snapshot in
username = snapshot.value! as! String
})
}
// other methods from AppDelegate.swift
}
And when you get to the desired ViewController, set your viewDidAppear function to this:
override func viewDidAppear(_ animated: Bool){
super.viewDidAppear(animated)
yourLabel.text = username
}
And you can just use your username anywhere in the current Module.
Hope it helps!