My app uses Firebase messaging and Google analytics. I am using this code to setup GAI:
var configureError: NSError?
GGLContext.sharedInstance().configureWithError(&configureError)
if let error = configureError {
print("Error configuring Google services: \(error)")
}
let gai = GAI.sharedInstance()
gai?.optOut = true
gai?.trackUncaughtExceptions = true
gai?.logger.logLevel = GAILogLevel.verbose
gai?.dispatchInterval = 120
_ = gai?.tracker(withTrackingId: FWKeys.googleTrackingID)
but on this step console says that I am using Firebase analytics instead:
<FIRAnalytics/INFO> Firebase Analytics enabled
Google analytics console doesn't show any active users when I start the app. Why is this happening?
UPD: For some reason information in the Analytics console started updating. But I am still wondering why there is "Firebase Analytics enabled" in the log while I am setting up GAI.
When you use any Firebase feature, such as Firebase Cloud Messaging in your case, the Firebase SDK also enabled Firebase Analytics. This does not replace Google Analytics, it is an additional analytics solution on top.
To disable Firebase Analytics, see the instructions in this answer: How to disable/remove FirebaseAnalytics.
Related
I am working on an app to interface and read from a google sheet.
I followed the quick-start guide in this link.
I am making requests to the Google Sheets API using an Oauth 2.0 client ID, but it is giving me an error stating the request had insufficient scopes (Error 403), but I am unsure why since that is the scope that is stated in the Quick-start guide? Not sure if the source of the error is in my setup in the Google Console or in my code below? I set up an Oauth 2.0 Client ID within the Google Console and copied that into my app adding it to one of the URL types in Xcode. I am using the kGTLRAuthScopeSheetsSpreadsheetsReadonly scope. Below is portion of my code performing the request in Swift.
private let service = GTLRSheetsService()
private let scopes = [kGTLRAuthScopeSheetsSpreadsheets, kGTLRAuthScopeSheetsSpreadsheetsReadonly, kGTLRAuthScopeSheetsDrive]
service.authorizer = GIDSignIn.sharedInstance().currentUser!.authentication.fetcherAuthorizer()
let range = "Class!A2:H"
let query = GTLRSheetsQuery_SpreadsheetsValuesGet
.query(withSpreadsheetId: spreadSheetID, range: range)
service.executeQuery(query, delegate: self, didFinish: #selector(ImportStrengthPlansVC.displayResultWithTicket(ticket:finishedWithObject:error:)))
I am using firebase in an iOS-Swift project in which I have to enable offline support for uploading posts, in the post there is a picture and caption just like Instagram, so what I want is when user is offline and he/she wants to upload a post, his/her picture get saved in cache and when user comes online that photo get uploaded and give back a download url that we can use for saving posts-details it in database.
sample code is:
let photoIDString = UUID().uuidString
let storageRef = Storage.storage().reference(forURL: "storage ref URL").child("posts").child(photoIDString)
storageRef.putData(imageData, metadata: nil, completion: { (metadata, error) in
guard let metadata = metadata else {
return
}
if error != nil {
return
}
storageRef.downloadURL(completion: { ( url, error ) in
guard let downloadURL = url else {
return
}
let photoUrl = downloadURL.absoluteString
self.sendDataToDatabase(photoUrl: photoUrl)
})
}
)
I want to know what changes should I make in my code to provide the offline capability. Any code snippet will help more.
The problem is better view as re-send to server when there is an error.
For your offline case, you can check if the error return is a network error, or manually check network connection availability.
You can create a re-send array of object
e.g
var resendList : [YourObjectType]
// when failed to send to server
resendList.append(yourFailedObject)
And then, 2 solutions:
Check the network connectivity manually and reupload in when the app become active in func applicationDidBecomeActive(_ application: UIApplication) in appDelegate. For checking connectivity you can try the method here: Check for internet connection with Swift But this has a problem that, the user has to go out the app and back again with network connected
Keep track(listen to notification) on the connectivity change, using a suggestion method by https://stackoverflow.com/a/27310748/4919289 and reupload it to server
and loop through all objects in resendList and re-upload again.
I am not an iOS developer, but I can share logical flow and some references.
When user clicks on upload: Check if network is available?
if yes: upload the post.
if no:
save the post to app storage or offline database
set broadcast receiver to receive broadcast when device comes online. This link may be helpful.
upload post when device comes online.
If you are looking for solution that is offered by Firebase, you may find more details here.
Firebase offers you plenty of ways to do this in their documentation. https://firebase.google.com/docs/database/ios/offline-capabilities
When uploading to the firebase server, it will queue itself and wait until it has a internet connection again to upload. If this happens to timeout or you want to do it your own way just attempt to upload with a completionHandler on the setValue or updateChild functions - if not successfully and the error message is because of internet, add it to a local cache to the phone with the data and the path to the firebase server.
onLoad, attempt the same upload again until it succeeds, once it succeeds - clear the local cache.
I am testing out using the Firebase SDK for iOS/macOS in my app (macOS app). i have installed the SDK´s using:
pod 'FirebaseCore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :tag => '4.8.2'
pod 'FirebaseAuth', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :tag => '4.8.2'
pod 'FirebaseStorage', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :tag => '4.8.2'
The installation works well and I can configure my app in AppDelegate using [FIRApp configure];
I wonder if I can use the SDK to log in the user to his/hers private Google Cloud storage (GCS)? I understand I can use the SDK for storing to GCS in the apps storage, but it would be nice to log in to the users own GCS to retrieve a list of buckets and files. If anyone has an example as for how to do this I would appreciate it. All examples I find are for anonymous storage logins.
Update:
I could specify that I was hoping that Firebase SDK would contain an authentication method that allowed me access to my own Google cloud storage account. Perhaps Firebase is not the right choice for this, but then I would be very interested in suggestions for alternative SDKs for Swift/objective-c login/upload/download to Google cloud storage.
You can indeed use the Firebase SDK for iOS to work with Firebase Cloud Storage (which in fact stores data in Google Cloud Platform Cloud Storage's buckets), using both Swift and Objective-C.
Firebase Cloud Storage in iOS
Regarding the usage of Cloud Storage buckets in your Firebase application, you can get started with this documentation page. First of all, you have to set up the proper security rules to the bucket: you can allow public access, access to only authenticated users, or even per-userID access. There are some sample rules that you can use to start working with this.
Once you have set up the appropriate access for Storage buckets (if each user has its own bucket, then I assume each user will have a GCP account with a private bucket and they will have to set up the configuration access themselves, as you will not have access to them), you can add the Cloud Storage dependencies to your iOS app:
pod 'Firebase/Core'
pod 'Firebase/Storage'
Then run pod install and you can already create the reference to Cloud Storage after initializing Firebase in your app (here you have a Swift sample code, but you can have a look at the Objective-C samples in the documentation too):
// Import and set up Firebase
import Firebase
FirebaseApp.configure()
// Create a storage reference
let storage = Storage.storage()
let storageRef = storage.reference()
// Refer to a child directory or even a file
let folderRef = storageRef.child("my_folder")
var fileRef = folderRef.child("my_file.txt")
And once you have all this, you can proceed to more complex guides, such as uploading files, downloading files or (important) handling errors. Bear in mind that these are just some examples of the things you can do following the step-by-step documentation, but feel free to move through all the pages in order to have a deeper understanding about how all this works.
Firebase Authentication for Cloud Storage in iOS
Also, regarding authentication, you can follow the same rules that you are probably already using for the rest of your Firebase application. Let me share this other page talking about some mechanisms to provide Firebase Authentication, and specifically how to provide Firebase Authetication on iOS.
I'm not sure I fully understand what you're asking. But if I do... This may help. I've used Google Storage to save photos. To access those photos I needed to store the URL to locate those photos. I did this in the Firebase Realtime Database. If you store a different type of file to a GCS, all you need is that URL to retrieve the data.
if let photoData = UIImageJPEGRepresentation(jpegRepresentation!, 1.0) {
storePhoto(photoData, angel.name!, completion: { (url, err) in
if err != nil {
print(err?.localizedDescription)
angelToSave["photo"] = nil
myAngelsRef.updateChildValues(angelToSave, withCompletionBlock: { (error, ref) in
if error != nil {
completion(error!)
} else {
completion(nil)
}
})
} else {
// ### HERE ####
angelToSave["photo"] = url?.absoluteString
angelNameRef.updateChildValues(angelToSave)
completion(nil)
}
})
}
func storePhoto(_ photo: Data, _ name: String, completion: #escaping (_ result: URL?, _ error: NSError?) -> Void) {
let storageRef = Storage.storage().reference().child(name)
storageRef.putData(photo, metadata: nil) { (storageMetaData, err) in
if err != nil {
completion(nil, NSError(domain: (err?.localizedDescription)!, code: 0, userInfo: nil))
} else {
completion(storageMetaData?.downloadURL(), nil)
}
}
}
After I saved the photo I was able to get the URL location and save that to an object I stored in the RTDB. Now when I pull the data from the use's RTDB I get the URL for the Storage data.
I recently updated to the new firebase that just came out a few days ago. Since it does not have a Cordova/Ionic special page, I assume that I would need to use the one for Web. I got everything set up, but the signInWithPopup function does not work on actual phone device. It works fine in web browser. I have whitelisted firebase before for the previous version and everything was working just fine for the previous version.Does anyone have any idea? Any help with be appreciated it!
firebase.auth().signInWithPopup(provider).then(function(result) {
// This gives you a Google Access Token. You can use it to access the Google API.
var token = result.credential.accessToken;
// The signed-in user info.
var user = result.user;
// ...
}).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
// The email of the user's account used.
var email = error.email;
// The firebase.auth.AuthCredential type that was used.
var credential = error.credential;
// ...
});
Here is what's in my content security policy
<meta http-equiv="Content-Security-Policy" content=" img-src 'self' data:
http://*.google.com
http://*.gstatic.com
http://*.googleapis.com
http://*.firebaseio.com
https://*.google.com
https://*.gstatic.com
https://*.googleapis.com
https://*.firebaseio.com
Finally I allowed naviagation for everything in my config.xml
<allow-navigation href="*" />
Popup and redirect doesnt work on mobile device. You may need to use cordovaOauth or any other 3rd party to get the access token, and then use signInWithCredential() to authenticate users and get the firebase user data.
Here is a good example:
http://www.clearlyinnovative.com/firebase-3-0-ionic-facebook-login
Currently Firebaseu V3 auth's signInWithPopup/Redirect do not work in cordova apps.
In my Ionic2 RC1 + Firebase3.5 + AngularFire2.beta5 project I had the same problem... Google Auth with Popup worked in Browser but not in my Android .APK
Firstly, I add 192.168.1.172 to my Firebase Console authorized domain list and <allow-navigation href="http://192.168.1.172:8100"/> to my config.xml.
After this, I found that installing Cordova InAppBrowser plugin solves my problem definitively.
I didn't need to modify my code, only plug and play, exactly like David East says in his Social login with Ionic blog.
I need to add Google login in my Ionic v2 app.
Currently I cannot use the Ionic Authentication service because it's not ready for v2 yet.
I've also tried the ng2-cordova-oauth plugin but I cannot use ionic serve or Ionic View to test the authentication which is a huge inconvenience for me because I no longer have an easy way to show the app to the client.
So... any alternative?
Firebase user authentication is an alternative , you can implement google authentification with few lines of code
var ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com");
ref.authWithOAuthPopup("google", function(error, authData) {
if (error) {
console.log("Login Failed!", error);
} else {
console.log("Authenticated successfully with payload:", authData);
}
});
please see the documentation here firebase documentation