Can't download file from Firebase Storage swift 4.2 - swift

I changed the permissions on the Firebase console and set to allow all users access without the need for an authentication.
I have the following code:
AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
{
FirebaseApp.configure()
Utils.initApp()
return true
}
Utils.swift
import Foundation
import Firebase
class Utils
{
static var inventoryJsonString = "Inventory/Inventory.json"
static var oneMB : Int64 = 1024 * 1024
static func initApp()
{
getJsonDate(inventoryJsonString)
}
static func getJsonData(filePath: String)
{
let storageRef = Storage.storage().reference()
let jsonRef = storageRef.child("Inventory")
jsonRef.getData(maxSize: self.oneMB)
{
extractedData, error in
print("a")
if let error = error{
print("b")
}
else
{
print("c")
}
}
}
I'm calling that function but nothing happnes - I don't get an error, yet I'm not getting the url (also tried with getData and got nothing). I tripple checked the path in filePath and it's correct.
What am I missing here?

I assume you're trying to read the actual json file, not all the files within the Inventory path
Here's your code with notes on how to fix:
class Utils
{
static var inventoryJsonString = "Inventory/Inventory.json" //NOT USED!
static var oneMB : Int64 = 1024 * 1024
static func initApp() {
getJsonDate(inventoryJsonString)
}
static func getJsonData(filePath: String) { //filePath is NOT USED!
let storageRef = Storage.storage().reference()
**this is a PATH to the enclosing directory only and not the JSON file**
let enclosingPathRef = storageRef.child("Inventory")
**add this to make it work**
let actualFileRef = enclosingPathRef.child("Inventory.json")
actualFileRef.getData(maxSize: self.oneMB) { extractedData, error in
if let error = error{
print("an error occurred: \(error.localizedDescription")
} else {
print("success!")
}
}
}
}

Related

Firebase iOS clicking on shortened link returns ' Receive failed with error "Software caused connection abort" '

I'm just going to paste in a couple of my files so that you can test this really easily and see what's going on. I'm clicking the button and it's making the shortened dynamic link. Then, I'm typing out the DynamicLink in the notes app and then I press the link. I get redirected to the app and the following error is returned:
[connection] nw_read_request_report [C1] Receive failed with error "Software caused connection abort"
Side note: all of this is being tested on an iPhone 7 (a physical device, not the simulator).
FirebaseTestApp and AppDelegate:
import SwiftUI
import Firebase
#main
struct FirebaseTestApp: App {
#UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
class AppDelegate: NSObject, UIApplicationDelegate {
var functionMaster: functions = functions()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
FirebaseApp.configure()
return true
}
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
let dynamicLink = DynamicLinks.dynamicLinks().dynamicLink(fromCustomSchemeURL: url)
if dynamicLink != nil {
print("Dynamic link : \(String(describing: dynamicLink?.url))")
return true
}
return false
}
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: #escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
print("Successful penetration")
guard let inComingURL = userActivity.webpageURL else { return false }
print("Incoming Web Page URL: \(inComingURL)")
self.functionMaster.handleIncomingDynamicLink(inComingURL)
return true
}
}
functions class:
import Foundation
import Firebase
import UIKit
class functions: ObservableObject {
func makeDynamicLink() {
var components = URLComponents()
components.scheme = "https"
components.host = "www.firebase-test.com" //this can be some random domain right? It doesn't have to actually exist yet?
components.path = "/data"
let stringifiedNumber = String(123)
components.queryItems = [stringifiedNumber]
let dynamicLinksDomainURIPrefix = "https://something.page.link"
guard let linkParameter = components.url else { return }
print("I am sharing \(linkParameter)")
guard let linkBuilder = DynamicLinkComponents(link: linkParameter, domainURIPrefix: dynamicLinksDomainURIPrefix) else { return }
if let myBundleId = Bundle.main.bundleIdentifier {
linkBuilder.iOSParameters = DynamicLinkIOSParameters(bundleID: myBundleId)
}
linkBuilder.iOSParameters?.appStoreID = "962194608"
linkBuilder.socialMetaTagParameters = DynamicLinkSocialMetaTagParameters()
linkBuilder.socialMetaTagParameters?.title = testLocation.name
linkBuilder.socialMetaTagParameters?.descriptionText = testLocation.address
linkBuilder.shorten { [weak self] (url, warnings, error) in
if let error = error{
print("Firebase encountered an error: \(error)")
return
}
if let warnings = warnings {
for warning in warnings {
print("Firebase Warning: \(warning)")
}
}
guard let url = url else { return }
print("The short URL is: \(url.absoluteString)")
self?.showShareSheet(url: url)
}
guard let longDynamicLink = linkBuilder.url else { return }
print("The long URL is: \(longDynamicLink)")
}
func showShareSheet(url: URL) {
let promoText = "Check out this thing I've marked in FirebaseTest!"
let activityVC = UIActivityViewController(activityItems: [promoText, url], applicationActivities: nil)
UIApplication.shared.windows.first?.rootViewController?.present(activityVC, animated: true)
}
func handleIncomingDynamicLink(_ dynamicLink: URL) {
_ = DynamicLinks.dynamicLinks().handleUniversalLink(dynamicLink) { (dynamiclink, error) in
guard error == nil else {
print("Found an error: \(error?.localizedDescription ?? "")")
return
}
print("Dynamic link : \(String(describing: dynamiclink?.url))")
let path = dynamiclink?.url?.path
var id = 0
if let query = dynamiclink?.url?.query {
let dataArray = query.components(separatedBy: "=")
id = Int(dataArray[1]) ?? 0
}
if path == "data" {
//Write code here
}
}
}
}
ContentView:
import SwiftUI
struct ContentView: View {
#ObservedObject var functionMaster: functions = functions()
var body: some View {
Button("Click me to run some firebase stuff") {
functionMaster.makeDynamicLink()
}
.padding()
}
}
In browser, when I navigate to https://something.page.link/apple-app-site-association, I get this:
https://i.stack.imgur.com/6Ndo0.png
Try installing the files for the the simulator you want to test on, update Xcode, delete all other versions.

Getting Thread: signal SIGABRT

Building an app with a chat feature and getting a SIGBRT error. It doesn't seem to be talking to the Firebase database. I checked all my outlets and they seem to all be intact and I didn't see any broken outlets.
the error I'm getting in the debug area is
"2018-08-21 01:09:15.479487-0400 Split App[83668:9375919] *** Terminating app due to uncaught exception 'FIRAppNotConfigured', reason: 'Failed to get default Firebase Database instance. Must call [FIRApp configure] (FirebaseApp.configure() in Swift) before using Firebase Database.... libc++abi.dylib: terminating with uncaught exception of type NSException"
class DataService{
static let dataService = DataService()
private var _BASE_REF = Database.database().reference()
private var _ROOM_REF = Database.database().reference().child("rooms")
var BASE_REF: DatabaseReference {
return _BASE_REF
}
var ROOM_REF:DatabaseReference{
return _ROOM_REF
}
var storageRef: StorageReference{
return Storage.storage().reference()
}
var fileURL: String!
// store the thumbnail in database
func CreateNewRoom(user: User, caption: String, data: NSData){
let filePath = "\(user.uid)/\
(Int(NSDate.timeIntervalSinceReferenceDate))"
let metaData = StorageMetadata()
metaData.contentType = "image/jpg"
storageRef.child(filePath).putData(data as Data, metadata: metaData){
(metadata, error) in if error != nil {
print ("Error Uploading: \(String(describing:
error?.localizedDescription))")
return
}
//create a url for data (photo thumbnail image)
_ = metadata?.storageReference?.downloadURL(completion: error as!
(URL?, Error?) -> Void)
if Auth.auth().currentUser != nil {
let idRoom = self.BASE_REF.child("rooms").childByAutoId()
idRoom.setValue(["caption": caption,"thumbnailURLFromStorage":
self.storageRef.child(metadata!.path!).description, "fileURL" :
self.fileURL])
}
}
}
func fetchDataFromServer(callback: #escaping (Room) -> ()){
DataService.dataService.ROOM_REF.observe(.childAdded){ (snapshot) in
let room = Room(key: snapshot.key, snapshot: snapshot.value as!
Dictionary<String, Any>)
callback(room)
}
}
func SignUp(username:String, email: String, password: String, firstName:
String, lastName: String, data: NSData){
Auth.auth().createUser(withEmail: email, password: password, completion:
{ (user, error) in
if error != nil {
print(error!)
}
else {
print("Registration Successful")
}
let changeRequest =
Auth.auth().currentUser?.createProfileChangeRequest()
changeRequest?.displayName = username
changeRequest?.commitChanges(completion: {(error) in
if let error = error {
print (error.localizedDescription)
return
}
})
let filePath = "profileimage/\(String(describing:
Auth.auth().currentUser!.uid))"
let metadata = FirebaseStorage.StorageMetadata()
metadata.contentType = "image/jpeg"
self.storageRef.child(filePath).putData(data as Data, metadata:
metadata, completion: {(metadata, error) in
if let error = error {
print ("\(error.localizedDescription)")
return
}
_ = metadata?.storageReference?.downloadURL(completion: error as!
(URL?, Error?) -> Void)
if let error = error {
print (error.localizedDescription)
return
}
else {
print ("Sweet!")
}
let appDelegate: AppDelegate = UIApplication.shared.delegate as!
AppDelegate
appDelegate.login()
})
}
}
You should follow these steps
Step 1 Import Firebase to your AppDelegate.swift
import Firebase
Step 2 call configure() in didFinishLaunchingWithOptions method in AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
FirebaseApp.configure()
return true
}
Hope it helps
You have not configured firebase yet .
So just inside you app delegate first import Firebase and inside the method didFinishLaunchingWithOptions configure firebase.
By writing a single line FirebaseApp.configure().

fetching firestore data in applicationDidFinishLaunchingWithOptions

I'm using firebase firestore and authentication .
My app is basically managing orders, when a user sends a new order to firestore it gets a openOrder default Boolean var, I have another app that manage this order and once my other app reads the order the boolean var changes value.
All of that works.
My issue is when a user closes completly the app and then reopens it I need to check if the openOrder is true or not and according to that set my rootViewController .
I'm using a completion handler to fetch the openOrder var and check if it is true or not but applicationDidFinishLaunchingWithOptions returns true before I set my local vars according to the firestore functions.
my code is :
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
let reValue = loadPriviousDishesIfUserQuitsAppBeforeClosingTab(completion: { success in
guard success! else { return }
//here I have all the values I need and need to return only here
})
return true
}
func loadPriviousDishesIfUserQuitsAppBeforeClosingTab(completion: #escaping (Bool?) ->()) {
db = Firestore.firestore()
let myUserID = Auth.auth().currentUser?.uid
db.collection("users").whereField("user", isEqualTo: myUserID!).whereField("openOrder", isEqualTo: true).getDocuments { (querySnapshot, error) in
if let err = error {
print(err.localizedDescription)
completion(nil)
}
else {
for doc in (querySnapshot?.documents)! {
guard let restID = doc.data()[ResttId"]
else {return}
myRestaurant.restID = restID as? String
self.setMyRestMenu(completion: { success in
guard success else { return }
//here I set all my values using fetching all the data from firestore,
})
}
completion(true)
}
}
}
You can show a loading activity above the rootViewController until get that value , then
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let reValue = loadPriviousDishesIfUserQuitsAppBeforeClosingTab(completion: { success in
guard success! else { return }
//here I have all the values I need and need to return only here
let stor = UIStoryboard.init(name: "Main", bundle: nil)
let welcomeView = stor.instantiateViewController(withIdentifier: "orderView")
let nav = UINavigationController(rootViewController: welcomeView )
nav.navigationBar.isHidden = true
self.window?.rootViewController = nav
})
return true
}
Edit : set storyboardID here

swift 3 facebook integration

trying to get Facebook connect working from a swift project.
Have been trying to follow along the following youtube video: https://www.youtube.com/watch?v=I6rTmfLp9aY
which unfortunately for me is in German.
so this is what I have so far:
I have my Facebook app with IOS enabled enabled and I planted my bundleID there.
Downloaded latest iOS framework and added to project
to the AppDelegate file I added:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
FBSDKApplicationDelegate.sharedInstance()
return true
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
FBSDKAppEvents.activateApp()
}
and this is the ViewController file
import UIKit
import FBSDKCoreKit
import FBSDKLoginKit
import FBSDKShareKit
class ViewController: UIViewController, FBSDKAppInviteDialogDelegate, FBSDKLoginButtonDelegate{
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
if (FBSDKAccessToken.current() != nil)
{
let content = FBSDKAppInviteContent()
content.appLinkURL = NSURL(string: "{Facebook link to app}") as URL!
FBSDKAppInviteDialog.show(from: self, with: content, delegate: self)
}
else
{
let loginView : FBSDKLoginButton = FBSDKLoginButton()
self.view.addSubview(loginView)
loginView.center = CGPoint(x: self.view.frame.midX, y: self.view.frame.midY + 100)
loginView.readPermissions = ["public_profile", "email"]
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func appInviteDialog (_ appInviteDialog: FBSDKAppInviteDialog!, didCompleteWithResults results: [AnyHashable : Any]!)
{
}
func appInviteDialog (_ appInviteDialog: FBSDKAppInviteDialog!, didFailWithError error: Error!) {
print("Error took place in appInviteDialog \(error)")
}
func loginButton(_ loginButton: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: Error!) {
if ((error) != nil)
{
//process error
}
else if result.isCancelled {
//handle cancelation
}
else {
let content = FBSDKAppInviteContent()
content.appLinkURL = NSURL(string: "{Facebook link to app}") as URL!
FBSDKAppInviteDialog.show(from: self, with: content, delegate: self)
if result.grantedPermissions.contains("email")
{
//do work
}
}
}
func loginButtonDidLogOut(_ loginButton: FBSDKLoginButton!) {
}
}
No errors and no alerts. When i run simulator I get an empty screen. Must be doing something right cause I get the following msg:
SystemGroup/systemgroup.com.apple.configurationprofiles
2017-06-04 00:42:02.351876+0300 facebook_login[4569:144075] [MC] Reading from private effective user settings.
also, if I just paste in viewDidLoad the following lines from the code:
let loginView : FBSDKLoginButton = FBSDKLoginButton()
self.view.addSubview(loginView)
loginView.center = CGPoint(x: self.view.frame.midX, y: self.view.frame.midY + 100)
loginView.readPermissions = ["public_profile", "email"]
I get a beautiful Facebook button in simulator that of course crashes when i press it.
any help to work will be greatly appreciated
Facebook has a Swift SDK you might find easier to use than the Objective-C one (which they just call iOS). Try looking around the documentation here:
https://developers.facebook.com/docs/swift
Also, follow the steps described in the (other) iOS SDK to get started:
https://developers.facebook.com/docs/ios/getting-started/
This is the minimal app delegate I could get to work (notice the Swift SDK is missing the FB prefixes that exist in the iOS SDK):
import UIKit
import FacebookCore
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
SDKApplicationDelegate.shared.application(application, didFinishLaunchingWithOptions: launchOptions)
return true
}
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
return SDKApplicationDelegate.shared.application(app, open: url, options: options)
}
}
And be sure to add all the required keys in your Info.plist or else you won't get authentication to work at all.
func loginButton(_ loginButton: FBSDKLoginButton!, didCompleteWith
result:FBSDKLoginManagerLoginResult!, error: Error!) {
if ((error) != nil) {
// Process error
print("Error! : \(error.localizedDescription)")
return
} else if result.isCancelled {
// Handle cancellations
print("Success! : user cancel login request")
return
} else {
let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me", parameters: ["fields" : "id, email, name,picture.type(large)"])
graphRequest.start(completionHandler: { (connection, result, error) -> Void in
if ((error) != nil) {
print("Error: \(error)")
} else {
// Do work in app.
let dataDict:NSDictionary = result as! NSDictionary
if let token = FBSDKAccessToken.current().tokenString {
print("tocken: \(token)")
let userDefult = UserDefaults.standard
userDefult.setValue(token, forKey: "access_tocken")
userDefult.synchronize()
}
if let user : NSString = dataDict.object(forKey: "name") as! NSString? {
print("user: \(user)")
}
if let id : NSString = dataDict.object(forKey: "id") as? NSString {
print("id: \(id)")
}
if let email : NSString = (result! as AnyObject).value(forKey: "email") as? NSString {
print("email: \(email)")
}
if let pictureData:NSDictionary = dataDict.object(forKey: "picture") as? NSDictionary{
if let data:NSDictionary = pictureData.object(forKey: "data") as? NSDictionary{
if let strPictureURL: String = data.object(forKey: "url") as? String{
self.imageviewUser.image = UIImage(data: NSData(contentsOf: NSURL(string: strPictureURL)! as URL)! as Data)
}
}
}
}
})
}
}
func loginButtonDidLogOut(_ loginButton: FBSDKLoginButton!)
{
FBSDKAccessToken.setCurrent(nil)
FBSDKProfile.setCurrent(nil)
let manager = FBSDKLoginManager()
manager.logOut()
}

Existing Realm Database notworking in swift 3.1 xcode 8

I created the application use existing database realm 2.3.0 and swift 3.1 xcode 8.3.
But when I try to access the realm database. there is an error.
Could not access database: Error Domain=io.realm Code=2 "Unable to open a realm at path '/Users/dodipurnomo/Library/Developer/CoreSimulator/Devices/858C796B-CBA8-424B-9A97-0893304B758B/data/Containers/Data/Application/A2D910EE-AAC5-4836-9FE7-97F744E802E5/Documents/Conversio.realm': Unsupported Realm file format version." UserInfo={NSFilePath=/Users/dodipurnomo/Library/Developer/CoreSimulator/Devices/858C796B-CBA8-424B-9A97-0893304B758B/data/Containers/Data/Application/A2D910EE-AAC5-4836-9FE7-97F744E802E5/Documents/Conversio.realm,
Above is an error message when I try to execute the database.
As for the class to hendleing the database realm is as follows:
import RealmSwift
import UIKit
class DBManager{
//MARK: - Singleton shared intance
static let sharedIntance = DBManager()
//MARK: - overide init function in realm
static var realm: Realm {
get {
do {
let realm = try Realm()
return realm
}
catch {
print("Could not access database: ", error)
}
return self.realm
}
}
public static func write(realm: Realm, writeClosure: () -> ()) {
do {
try realm.write {
writeClosure()
}
} catch {
print("Could not write to database: ", error)
}
}
public static func query(realm: Realm,queryClosure: () -> ()){
}
func save(entityList: [Object], shouldUpdate update: Bool = false) {
DBManager.realm.beginWrite()
for entity in entityList {
if let key = type(of: entity).primaryKey(), let value = entity[key] , update {
if let existingObject = DBManager.realm.object(ofType: type(of: entity), forPrimaryKey: value as AnyObject) {
let relationships = existingObject.objectSchema.properties.filter {
$0.type == .array
}
for relationship in relationships {
if let newObjectRelationship = entity[relationship.name] as? ListBase , newObjectRelationship.count == 0 {
entity[relationship.name] = existingObject[relationship.name]
}
}
}
}
DBManager.realm.add(entity, update: update)
}
do {
try DBManager.realm.commitWrite()
} catch let writeError {
debugPrint("Unable to commit write: \(writeError)")
}
DBManager.realm.refresh()
}
}
And I set the Realm in appdelegate as follows:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
let desPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
let fullDesPath = URL(fileURLWithPath: desPath).appendingPathComponent("Conversio.realm")
var config = Realm.Configuration()
config.deleteRealmIfMigrationNeeded = true
config.fileURL = fullDesPath
Realm.Configuration.defaultConfiguration = config
chekDB()
return true
}
//chek database
func chekDB() {
let bundleDB = Bundle.main.path(forResource: "Conversio", ofType: "realm")
let desPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
let fileManager = FileManager.default
let fullDesPath = URL(fileURLWithPath: desPath).appendingPathComponent("Conversio.realm")
let fullDestPathString = String(describing: fullDesPath)
if fileManager.fileExists(atPath: fullDesPath.path){
print("Database file is exis !")
print(fileManager.fileExists(atPath: bundleDB!))
}else{
do{
try fileManager.copyItem(atPath: bundleDB!, toPath: fullDesPath.path)
}catch{
print("error encured while copying file to directori \(fullDestPathString)")
}
}
}
The error message you're getting means that realm file was created with newer version of Realm, so update Realm to the latest version.
Also keep in mind if you open realm with Realm Browser that uses a newer version of realm it asks you to convert the file format. If you do that you can open this realm with older version of realm-cocoa.