Following various tutorials most of which seem to be from a couple years ago, I am trying to connect to Firebase from an IOS app and having trouble with how and where to import the libraries and, in turn, connect to the database.
In my app delegate, I am able to establish a connection--I think---inside the difFinishLaunching method (I say I think because Firebase does not recognize the app in the console but this seems to be a frequent occurrence so I'm ignoring that and just trying to get the app to build in Xcode for now) as follows:
import UIKit
import FirebaseAnalytics
import FirebaseDatabase
import FirebaseCore
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
FirebaseApp.configure()
let myDB = Database.database().reference().child("items")
}
return true
}
That seems okay in that it builds.
When I try to put a reference to the database in a viewcontroller, however, it throws an error on Database:
import UIKit
import FirebaseCore
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
let ref = Database.database().reference(withPath: "items") //THIS LINE THROWS ERROR
What do I need to do to create a property for the Database in a view controller?
Edit: Looking at some other answers on SO, it seems I may have to create a singleton reference to the db connection. If so, where would I put this and how would I reference it?
Thanks for any suggestions
First, your AppDelegate should look something like this
import UIKit
import Firebase
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
return true
}
then, in your first viewController like this:
import UIKit
import Firebase
class ViewController: UIViewController {
var db: Firestore!
override func viewDidLoad() {
super.viewDidLoad()
self.db = Firestore.firestore()
//do something with Firestore
var ref: DocumentReference? = nil
ref = db.collection("users").addDocument(data: [
"first": "Ada",
"last": "Lovelace",
"born": 1815
]) { err in
if let err = err {
print("Error adding document: \(err)")
} else {
print("Document added with ID: \(ref!.documentID)")
}
}
}
}
Keep in mind I have set my Firestore rules to allow anyone to read/write, which is dangerous so please start working through the Authentication guide once you get this working.
Note that the above code pretty much came straight from the Getting Started guides Add Firebase To An App and Installation and setup
Related
I am very new to both firebase and Xcode SwiftUI. I found many tutorial on the storyboard but could not find tutorials for SwiftUI. I downloaded firebase using pod and the instruction given to us by the firebase documents. I created an AppDelegate.swift and copied the following code:
import Foundation
import UIKit
import Firebase
import SwiftUI
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions:
[UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
return true
}
}
In the Firebase database, I created a user collection with an example value to test if it works.
So by using this link https://firebase.google.com/docs/firestore/quickstart?authuser=0#swift_3, I looked at the read data section and wrote the code in the ContentView.swift:
db.collection("users").getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
print("\(document.documentID) => \(document.data())")
}
}
}
But It says that it has to be a view.
How can I get the data in the firebase database into my Swiftui app?
Based on advice, I would like to manage API keys using Firebase Remote Config to avoid hard-coding API keys like google_maps_flutter suggests. It has an AppDelegate.swift like:
import UIKit
import Flutter
import GoogleMaps
#UIApplicationMain
#objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GMSServices.provideAPIKey("YOUR KEY HERE")
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
How can the above be modified to fetch the API key from Firebase Remote Config and then pass it to GMSServices?
Based on this article, I came up with:
import UIKit
import Firebase
import Flutter
import GoogleMaps
//import os.log
#UIApplicationMain
#objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
FirebaseApp.configure()
RemoteConfig.remoteConfig().fetchAndActivate() { status, error in
let apiKey : String = RemoteConfig.remoteConfig()["Google_Maps_SDK_for_iOS_API_KEY"].stringValue ?? "MISSING";
// os_log("Google_Maps_SDK_for_iOS_API_KEY = '%#'", apiKey)
GMSServices.provideAPIKey(apiKey)
}
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
Is there a better way?
I was thinking of making this as a comment, but decided to make it as my answer as it was too long.
I think it's one way of getting keys from remoteConfig, but again failure can happen where fetch config was not retrieved. One way to solve it is by having a force refresh when it fails, but then again you are relying on firebase for those keys and if for some reason (experienced it before firebase was acquired by google) it went down your app then will be unuseable (so as for many apps).
For me, I still put my API keys bundled with the app just to make sure all the important functionality works.
Another option will be having your API Keys bundled and then having a WebService call to check for new keys once the current keys you have has expired/change. That way you have the capability to immediately expire your keys and change it to another one.
I am new to firebase and trying to write some data to firebase.
My problem is below :
installed pod 'Firebase/Core'
pod 'Firebase/Database' coacopods
and import Firebase in Xcode, also changed realtime database rule both "read" and "write" are true, everything is connected to google firebase, but still can't write data in realtime database? anyone has same problem like me? can anyone help me to fix it?
code
part one(AppDelegate.swift):
import UIKit
import Firebase
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
**FirebaseApp.configure()**
return true
}
part two(ViewController.swift):
import UIKit
import Firebase
import FirebaseDatabase
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
**let ref = Database.database().reference()**
**ref.child("someid/name").setValue("mike")**
}
}
There is no any error message showing in Xcode or firebase.
I suggest you update your GoogleService-Info.plist by downloading from your console again. This solved my problem.
override func viewDidLoad() {
super.viewDidLoad()
let ref = Database.database().reference()
let value = [
"name": "mike"
] as [String: Any]
ref.child("someid/name").setValue(value)
}
So I am attempting to integrate Google's Firebase into my SpriteKit game and was having a small issue.
The instruction from Firebase is..."Configure a FIRApp shared instance, typically in your application's application:didFinishLaunchingWithOptions: method:FirebaseApp.configure()".
Now I've located the file called AppDelegate.swift in my Xcode project but when I place it into the first function, which matches the named one in the instructions I get the following error Use of unresolved Identifier FirebaseApp.
And I remembered to import Firebase at the top of document. Any suggestions?
It is FIRApp, not FirebaseApp.
FIRApp.configure()
Note: Don't forget to import the Firebase module.
import Firebase
Your app delegate needs to look something like this:
import UIKit
import Firebase
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
FIRApp.configure()
return true
}
}
Make sure you call FIRApp.configure() before the return true and remember to import Firebase.
After upgrading to Xcode 6.3 6D570 (and Swift 1.2), the init of a subclassed object does not compile.
Let's say I have a class called Armor, which inherits from PFObject, PFSubclassing (exactly as Parse documentation says).
When I try to create an instance, like var armor = Armor(), I get the following compile error:
Missing argument for parameter 'className' in call
Then I read in Parse docs that I should use the 'object' class method to init a subclassed object. So I tried to init like this: var armor = Armor.object().
But then I get the following compile error:
'object()' is unavailable: use object construction 'PFObject()'
I'm using Parse SDK version 1.7.1.
I also override the parseClassName method as follows:
class func parseClassName() -> String {
return "Armor"
}
I registered the subclass inside the initialise method and on app delegate before I setup Parse:
override class func initialize() {
var onceToken : dispatch_once_t = 0;
dispatch_once(&onceToken) {
self.registerSubclass()
}
}
How should I properly init a subclassed object?
=========================================================================
THIS HAS BEEN FIXED IN 1.7.3 PARSE SDK
You can download the new version here:
https://parse.com/docs/downloads
=========================================================================
Though docs are not clear on that, using .object() in Swift is not required anymore.
as said here and in the Swift code snippet found here
Now, this is weird but to make Armor() work you need to reference PFUser class somehow in the same file. Maybe it doesn't have to be PFUser but I havent dug deeper into it.
So, this won't work
import UIKit
import Parse
import Bolts
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
Parse.setApplicationId("appID", clientKey: "clientKey")
let myArmor = Armor()
return true
}
}
But this will
import UIKit
import Parse
import Bolts
private let fix = PFUser.hash() // here's the weird trick
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
Parse.setApplicationId("appID", clientKey: "clientKey")
let myArmor = Armor()
return true
}
}
Hope this helps and Parse pushes a fix out soon.
Also reported as a bug
register the class as a subclass in the AppDelegate, but before Parse.initialize is called.
Then you can delete the overwritten function initialize
This would make:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]!) -> Bool {
Armor.registerSubclass()
// Further initialization
return true
}
then just initialize the class by calling the constructor:
var myArmor = Armor()