How do you use Firebase within a custom class? - swift

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()
}
}

Related

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 i connect the firebase Firestore to my swift app

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

Failed to get FirebaseApp instance even though I used FirebaseApp.configure()

I'm trying to use firebase firestore but keep getting this error:
Thread 1: "Failed to get FirebaseApp instance. Please call FirebaseApp.configure() before using Firestore"
This happens even though I do call FirebaseApp.configure() here:
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
FirebaseApp.configure()
return true
}
}
And I have been using firebase authentication with no problems. Anyone know how to fix this?

AppTransparencyTracking not working in Swift UI

Since SwiftUI doesnt have a Appdelegate file, I tried adding it through App.swift file.
However, it still doesnt work. What am i missing ?
imported the libraries
import AppTrackingTransparency
import AdSupport
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {func requestIDFA() {
ATTrackingManager.requestTrackingAuthorization(completionHandler: { status in
// Tracking authorization completed. Start loading ads here.
// loadAd()
})
}
Then called the appdelegate under #main
#main
struct MyApp: App {
#UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
If you look at the didFinishLaunchingWithOptions function. You have a call function inside another function so the requestIDFA never calls.
Put your requestIDFA() function out side the didFinishLaunchingWithOptions and call inside the didFinishLaunchingWithOptions.
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
requestIDFA()
return true
}
func requestIDFA() {
ATTrackingManager.requestTrackingAuthorization(completionHandler: { status in
// Tracking authorization completed. Start loading ads here.
// loadAd()
})
}
}
Note: Make sure you have an added key to your Info.plist.
<key>NSUserTrackingUsageDescription</key>
<string>Your reason, why you want to track the user</string>

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!