I am completely new to Swift, Xcode and programming on Mac.
I have started working on some kind of app, and all I really did was add Firebase (Which worked), and then try to add Google Sign In. Nothing else exists really. So There really was a Google Sign In Button. I think the crash started happening when I connected a property to the Google Sign In Button.
Alas, I am new to this, and I don't even know how to debug properly. Can someone please be of assistant ?
My code :
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
{
// Override point for customization after application launch.
FirebaseApp.configure()
GIDSignIn.sharedInstance().clientID =
FirebaseApp.app()?.options.clientID
GIDSignIn.sharedInstance().delegate = self
return true
}
override func viewDidLoad()
{
super.viewDidLoad()
GIDSignIn.sharedInstance().uiDelegate = self
}
This is the property:
#IBOutlet weak var googleLoginButton: GIDSignInButton!
And then try to run your project so you get that line where you app crashes
Related
I've integrated Chartboost into my app and I am able to see ads, but I don't have a firm grasp of delegates and I am having trouble using the Chartboost provided code to cause actions to occur after an ad is viewed. My app delegate code is below (i replaced the actual appid and signature that I'm using):
class AppDelegate: UIResponder, UIApplicationDelegate, ChartboostDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
application.isStatusBarHidden = true
Chartboost.start(withAppId: "appID", appSignature: "appSignature", delegate: self)
Chartboost.cacheRewardedVideo(CBLocationHomeScreen)
Chartboost.cacheInterstitial(CBLocationHomeScreen)
func didDisplayInterstitial(_ location: String!){print("didDisplayI")}
func didCloseInterstitial(_ location: String!){print("didCloseI")}
func didDismissInterstitial(_ location: String!){print("didDismissI")}
return true
}
Then in my ViewController I have the following:
class CharacterCreationViewController: UIViewController, ChartboostDelegate {
weak var delegate: ChartboostDelegate?
Override func viewDidLoad() {
super.viewDidLoad()
Chartboost.setDelegate(self)
}
#IBAction func watchAd(_ sender: Any) {
Chartboost.showInterstitial(CBLocationLevelStart)
delegate?.didDismissInterstitial!(CBLocationLevelStart)
delegate?.didCloseInterstitial!(CBLocationLevelStart)
delegate?.didDisplayInterstitial!(CBLocationLevelStart)
}
The watchAd function is a button, and when I press it the ad runs, but none of the actions in the appDelegate file run once the ad is completed/dismissed/closed.
I've searched StackOverflow and the Chartboost help sections and messaged Chartboost support but I'm struggling to find where I've gone wrong.
I have an iOS (Swift) app with the following code in the AppDelegate:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
FIRApp.configure()
FIRDatabase.database().persistenceEnabled = true
return true
}
The app crashes on the persistenceEnabled = true line, with exception FIRAppNotConfigured, and the message "Failed to get default FIRDatabase instance. Must call FIRApp.configure() before using FIRDatabase."
Obviously, I've called FIRApp.configure() immediately before this, so the suggested solution is incorrect. The log output even shows "Configuring the default app" when that is called.
What might the problem be, and how could I resolve it so I can use the FIRDatabase?
Try:
override init() {
// Firebase Init
FIRApp.configure()
}
I've been debugging my application which uses Firebase for memory leaks, and after some time digging into my code I've found that the actual problem is the FIRApp.configure() it inside my application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) in AppDelegate.
As far as I know everything is configured in the right way, I'm using cocoa pods for installing and updating firebase. I'm also modifying my statusBar inside my AppDelegate the code is as follows:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
FIRApp.configure()
setStatusBarBackgroundColor(UIColor(red: 231/250, green: 97/250, blue: 44/250, alpha: 1.0))
// Override point for customization after application launch.
return true
}
var window: UIWindow?
override init() {
}
func setStatusBarBackgroundColor(color: UIColor) {
guard let statusBar = UIApplication.sharedApplication().valueForKey("statusBarWindow")?.valueForKey("statusBar") as? UIView else {
return
}
statusBar.backgroundColor = color
}
I'm also showing the instruments tool to show more details on the leak:
And I'm sure it's the FIRApp.configure() because I removed it for testing and there were no leaks.
Hope anyone has an idea on how to fix this leak, thank you.
I have the same problem. After some digging, it seems like Firebase Analytics is the one causing the leak.
Here is what I did:
set FIREBASE_ANALYTICS_COLLECTION_ENABLED to NO
FIREBASE_ANALYTICS_COLLECTION_DEACTIVATED to YES in GoogleServiceIn-info.plist.
At least this works for me. For those who rely on firebase analytics this definitely is a bug.
I'm trying to upgrade my app to the new version of Firebase. I went through the setup guide and edited all of my code to match the new syntax. However, when I run the app, I get these two errors.
The default app has not been configured yet.
Terminating app due to uncaught exception 'MissingDatabaseURL', reason: 'Failed to get FIRDatabase instance: FIRApp object has no databaseURL in its FirebaseOptions object.'
I have FIRApp.configure() in the AppDelegate and I have the GoogleServices-Info.plist imported into my project. The plist has all of the correct info as well. Anyone else running into this or know how to fix it?
Here's the answer to your problem:
To configure Firebase you have to execute FIRApp.configure() somewhere. After this is done you can use let firebaseDatabaseReference = FIRDatabase.database().reference() to get a reference to that database and start using it. The problem isn't with Firebase "per se" but with how Swift behaves.
If you put FIRApp.configure() in your AppDelegate func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool and then in the MyDatabase class you use let firebaseDatabaseReference = FIRDatabase.database().reference() outside of your declared functions sometimes the code FIRDatabase.database().reference() executes before the application didFinishLaunchingWithOptions function is executed.
Essentially your class is trying to get a reference to the Firebase database before it has a chance to configure itself, generating the error in the console "The default app has not been configured yet."
Note: This doesn't happen all the time, sometimes the application is slow to start, in iOS Simulator for example, and it doesn't have a chance to finish before MyDatabase "let" executes and tries to get a reference.
That is why moving the FIRApp.configure() code to override init() in AppDelegate works, essentially it makes sure the configure code gets executed when AppDelegate is initialised (in this and most cases, before MyDatabase is initialised)
override init() {
super.init()
FIRApp.configure()
// not really needed unless you really need it FIRDatabase.database().persistenceEnabled = true
}
Also make sure you super.init() (so you super classes get the "message") so you override doesn't do more harm than good.
I'm also using Fabric and in my case it was the order of Fabric and Firebase initializations. I had to initialize Firebase first.
So changing
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
Fabric.with([Crashlytics.self])
FirebaseApp.configure()
...
}
to:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
Fabric.with([Crashlytics.self])
...
}
fixed the problem.
In AppDelegate.m, outside of didFinishLaunchingWithOptions,
override init() {
FIRApp.configure()
FIRDatabase.database().persistenceEnabled = true
}
Make sure you are having DATABASE_URL key in your GoogleService-Info.plist
Swift 5 - Easy Solution
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
return true
}
//MARK:- This function will auto run and firebase will configure successfully
override init() {
super.init()
FirebaseApp.configure()
// not really needed unless you really need it
FIRDatabase.database().persistenceEnabled = true
}
Happy Coding
iOS 9.2
Swift 2.1.1
Xcode 7.2.1
Mac OSX 10.10.5
Same error here using the following code:
AppDelegate.swift:
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
FIRApp.configure()
return true
}
ViewController.swift:
import UIKit
import Firebase
class ViewController: UIViewController {
var db = FIRDatabase.database().reference()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//Create some data in Firebase db:
db.child("key").child("subkey").setValue("hello world")
}
I also added the file GoogleService-Info.plist to my project directory as described in the Firebase Getting Started Guide.
And I made my Firebase db public with the following Rules:
{
"rules": {
".read": true,
".write": true
}
}
Making the following changes to ViewController.swift is what worked for me:
class ViewController: UIViewController {
var db: FIRDatabaseReference!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
db = FIRDatabase.database().reference()
db.child("key").child("subkey").setValue("hello world")
}
Prior to running my app, my Firebase db looked like this:
myiosdata-abc123: null
After running my app, my Firebase db looked like this:
myiosdata-abc123
- key
|
+--- subkey: “hello world”
I had several normal working projects with FIRApp.configure () code in AppDelegate.swift:
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
FIRApp.configure()
return true
}
Everything worked great for quite some time, but yesterday and today I opened a Swift 3 project inside my Xcode 7.3.1 (I am still working in Swift 2, but opened Swift 3 project to see what is changed), and suddenly in all my Swift 2 apps and projects that I am still working on, got the same error:
The default app has not been configured yet
Every project now when I open in XCode, getting same error, I didn't know what to do, but after implementing #MichaelWilliams' code, everything works fine again.
I have debug my Xcode (clear and reload console), but nothing works beside this new approach by Michael.
This one resolved my problem:
override init() {
FIRApp.configure()
FIRDatabase.database().persistenceEnabled = true
}
Can this new code somehow make my app's unstable and can I be afraid to see problems with connecting/working with Firebase database now?
Try re-download GoogleService-Info.plist from your console and add it to your project, That worked for me!
If you are using Xcode 9, Swift 4 and Firebase 4 please do the following:
override init() {
FirebaseApp.configure()
Database.database().isPersistenceEnabled = true
}
The cleanest solution to me here is to have lazy properties in case you want to have the db on top of your file. So let's say you have a FirebaseService class where you want to have Firestore.firestore() db constant to use it in all of the functions in that class:
private lazy var db = Firestore.firestore()
Or if you are using Firebase Storage:
private lazy var storage = Storage.storage().reference()
Also keep in mind that if you are referencing the Database/Storage in init() of your classes, you still might have the same problem so avoid that.
Let me apologize first, just learning swift, so I am not 100% on what I am doing. I have found many tutorials on integrating a facebook login in swift and have what appears to be working in the app, but it seems my delegates are never getting called. What I expect to happen is when a user logins 2 things should happen.
1) The login button for facebook should change to a logout button.
2) A console command should print that I logged in, and ultimately user information.
ViewController Class is:
class ViewController: UIViewController,FBLoginViewDelegate {
#IBOutlet var fbLoginView : FBLoginView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.fbLoginView.delegate = self
self.fbLoginView.readPermissions = ["public_profile", "email", "user_friends"]
}
// Facebook Delegate Methods
func loginViewShowingLoggedInUser(loginView : FBLoginView!) {
println("User Logged In")
println("This is where you perform a segue.")
}
func loginViewFetchedUserInfo(loginView : FBLoginView!, user: FBGraphUser){
println("User Name: \(user.name)")
}
func loginViewShowingLoggedOutUser(loginView : FBLoginView!) {
println("User Logged Out")
}
func loginView(loginView : FBLoginView!, handleError:NSError) {
println("Error: \(handleError.localizedDescription)")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
AppDelegate sections are:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
FBLoginView.self
FBProfilePictureView.self
func application(application: UIApplication, openURL url: NSURL, sourceApplication: NSString?, annotation: AnyObject) -> Bool {
var wasHandled:Bool = FBAppCall.handleOpenURL(url, sourceApplication: sourceApplication)
return wasHandled
}
return true
}
As you can see, most of this is straight from the tutorials but is not working correctly. I've got my info.plist configured, and the FBLoginView appears and goes thru the entire authentication, but nothing is printed to console and the button doesn't change. When I try to click it again, I get app already authorized, which should mean that the auth was successful, but nothing got triggered back in my app.
I feel confident that something is probably wrong with my appdelegate but being new to swift, I have no clue what..
Facebook as changed SDk. Please find the latest solution here
http://www.brianjcoleman.com/tutorial-how-to-use-login-in-facebook-sdk-4-0-for-swift/
I would like to suggest you the cheking of these steps:
-in your VC class, import FacebookSDK statement and FBLoginViewDelegate ?
- your outlet should be:
//FB outlet
#IBOutlet var fbLoginView: FBLoginView
- in your AppDelegate.swift, also imported the FacebookSDK ?
- you have a func in a func in your AppDelegate.swift.It should be:
import FacebookSDK
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
//FB implementation
FBLoginView.self
FBProfilePictureView.self
return true
}
//FB Method handles what happens after authentication
func application (application:UIApplication, openURL url:NSURL, sourceApplication:NSString?, annotation:AnyObject) -> Bool {
//test var
var wasHandled:Bool = FBAppCall.handleOpenURL(url, sourceApplication: sourceApplication)
// attempt to extract a token from the url
return wasHandled
}