I'm trying to setup password-less email authentication through firebase for my iOS app. I'm using the method send signInLink which require actionCodeSettings and in turn a url. I've discovered that this url has to be a dynamic link created on Firebase. I've gone to the firebase console and white-listed a domain, but when I try to create the dynamic link on the console, I get "An error occurred when creating new dynamic link".
I'm a little confused as to how I'm supposed to construct this dynamic link especially the deep link. I've been through Firebase's documentation, added a dummy App Store ID and App prefix (as I was told by Firebase support), but I can't seem to get a proper diagnosis behind this
If I try sending the sign-in email there is no issue, but when I click on the link I get a 400 error saying "The requested URL was not found on this server".
Can anyone help me out with this?
actionCodeSettings.handleCodeInApp = true
actionCodeSettings.url = URL(string: String(format: "my_dynamic_link", email.text!))
actionCodeSettings.setIOSBundleID(Bundle.main.bundleIdentifier!)
actionCodeSettings.setAndroidPackageName("", installIfNotAvailable: false, minimumVersion: "12")
Auth.auth().sendSignInLink(toEmail: email.text!, actionCodeSettings: actionCodeSettings, completion: { error in
if error != nil {
print("Link Error: " + (error?.localizedDescription)!)
let castedError = error as NSError?
let FBError = AuthErrorCode(rawValue: (castedError?.code)!)
switch FBError {
case .invalidEmail?:
print("invalid email")
case .emailAlreadyInUse?:
print("in use")
default:
print("Create User Error: \(error!)")
}
}
else {
print ("No Error")
}
})
You could try following the troubleshooting steps mentioned in the Firecasts video "Getting started with Firebase Dynamic Links on iOS - Pt.1 (Firecasts)" at 7:54 (https://youtu.be/KLBjAg6HvG0?t=474).
I was having the same issue and everything worked fine after:
deleting the app
restarting my phone
reinstalling the app
Currently the bug radar (http://www.openradar.me/radar?id=4999496467480576) is still open.
Related
I have been using Firebase Auth (phone) in the app for a long time and have never had a problem
Today a user got that error on iOS device
The OAuth client ID provided is either invalid or does not match the specified API key
Since only one user got this error, I need to debug this carefully
PhoneAuthProvider.provider().verifyPhoneNumber(
number.getFormattedPhoneNumber(format: .E164)!,
uiDelegate: nil,
completion: { verificationID, error in
DispatchQueue.main.async {
if let error = error {
//print error
}
//logic
}
})
I use the above code to verify the phone number
What could cause that error on that user's device?
EDIT: I updated the app with iOS 15 SDK Xcode and the user that had this issue has iOS 14, could be any relation between them?
I've been trying to use the verifyReceipt endpoint to verify in-app purchase transactions with no success.
Here's how I'm doing it.
1. Read the receipt data in iOS (this is copy paste from Apple's documentation):
if let appStoreReceiptURL = Bundle.main.appStoreReceiptURL,
FileManager.default.fileExists(atPath: appStoreReceiptURL.path) {
do {
let receiptData = try Data(contentsOf: appStoreReceiptURL, options: .alwaysMapped)
print(receiptData)
let receiptString = receiptData.base64EncodedString(options: [])
// sendReceiptToBackEnd(receiptString)
}
catch { print("Couldn't read receipt data with error: " + error.localizedDescription) }
}
2. In the backend, I followed this advice from Apple:
As a best practice, always call the production URL for verifyReceipt first, and proceed to verify with the sandbox URL if you receive a 21007 status code.
So first I try this (python code):
data = {
'receipt-data': receipt_string, # this is what we get from the frontend
'password': settings.APP_STORE_SHARED_SECRET
}
url = 'https://buy.itunes.apple.com/verifyReceipt'
response = requests.post(url, json=data)
response_data = response.json()
status = response_data['status']
Status here is 21007, which is expected according to the advice above. So then I try the sandbox:
url = 'https://sandbox.itunes.apple.com/verifyReceipt'
response = requests.post(url, json=data)
response_data = response.json()
status = response_data['status']
And I get 21002 - which means there's probably something wrong with what I sent.
Initially I was trying to test this using Xcode locally, but I found out later that verifyReceipt doesn't work with this feature because app's are not signed by the App Store. So I deleted the local configs and set the StoreKit Configuration in scheme back to none, and verified the app is using the App Store Connect as it was picking up any changes I made there in the price.
I'm out of ideas on how to debug this further, so I'm wondering could it be because the App & IAPs are not submitted yet? Currently the app is in the "Prepare for Submission" state, and the IAPs are in the "Ready to Submit" state. Or maybe there is something else I'm missing?
Edit: The answer to my question is "yes, you can." I copied and pasted the json and sent it manually using Postman and it worked fine so something is happening in the backend. I'm leaving the question for reference but if someone recommends deleting please let me know.
I saw your edit, but just as a follow-up code 21002 is a "malformed body" response (or theoretically an Apple server issue, but I've only seen it when mangling the receipt data).
You can see the full list of codes and meanings here:
https://developer.apple.com/documentation/appstorereceipts/status
Incidentally, as you build our your server to process iTunes responses you may find this guide useful for processing the receipt on the server:
https://www.namiml.com/blog/app-store-verify-receipt-definitive-guide
When I try to authenticate access to write to a user's mindful minutes store (health app) from the onboarding in my own app, the authentication page doesn't display (although I did have this working in previous versions of the app). The app however doesn't crash and there is only the following message in the debugger:
Error Domain=com.apple.healthkit Code=3 "Failed to look up source with bundle identifier "com.myorg.myapp"" UserInfo={NSLocalizedDescription=Failed to look up source with bundle identifier "com.myorg.myapp"}
The code I am using to request the authentication is as follows:
let typesToShare = Set([
HKObjectType.categoryType(forIdentifier: HKCategoryTypeIdentifier.mindfulSession)!
])
self.healthStore.requestAuthorization(toShare: typesToShare, read: nil) { (_, error) -> Void in
if let error = error {
print("\(error)")
}
DispatchQueue.main.async {
self.performSegue(withIdentifier: "openWalkthroughThree", sender: self)
}
}
I have searched around the internet but can't seem t find anyone with the same issue. I have also checked my entitlements for HealthKit as well as usage description but they both seem to be fine - as I said, I had this working in previous versions of my app.
I would be grateful for any help you could give me in finding a solution to this problem.
Not sure what's going on but simply restarting my device fixed this issue.
Also see: Missing HealthKit Entitlement
I have successfully saved a CKShare URL to CloudKit, and I can see that the user is INVITED in the CloudKit Dashboard. My Mac app emailed the URL to that person, but when they click it, all they see it this screen on icloud.com:
Clicking OK makes everything disappear so all you see is the background on the web page.
My understanding is that the URL is supposed to open my Mac app where it will fire userDidAcceptCloudKitShareWith in my app delegate. But it does nothing.
Could this be because my app is in development and not in the Mac App Store yet? Do I need a custom URL scheme to get it to open my app?
Documentation on this stuff is pretty sparse. I'd love any help someone can provide.
I have since learned that you must specify a fallback URL for your CloudKit container. In cases where the app isn't installed (or isn't recognized, which seems to be the case when doing dev builds in Xcode like I am), CloudKit will forward share URL to somewhere you specify. They append the unique share ID to the URL so that you can process it on your own web page.
In the CloudKit dashboard, go to Environment Settings... and you'll see this popup:
I have it redirect to https://myapp.com/share/?id= and on my web page where it redirects to, I do a $_GET['id'] to grab the id. I then do another redirect to my application using a custom URL scheme and pass the share ID (e.g. myapp://abc123 where abc123 is the share ID).
In my app delegate, I receive the URL like this:
func application(_ application: NSApplication, open urls: [URL]) {
if let url = urls.first, let shareId = url.host{
fetchShare(shareId) //<-- sharedId = abc123
}
}
I then use CKFetchShareMetadataOperation to look up the URL of the share and CKAcceptSharesOperation to accept it like this:
func fetchShare(shareId: String){
if let url = URL(string: "https://www.icloud.com/share/\(shareId)"){
let operation = CKFetchShareMetadataOperation(shareURLs: [url])
operation.perShareMetadataBlock = { url, metadata, error in
if let metadata = metadata{
//:::
acceptShare(metadata: metadata)
}
}
operation.fetchShareMetadataCompletionBlock = { error in
if let error = error{
print("fetch Share error: \(error)")
}
}
CKContainer.default().add(operation)
}
}
func acceptShare(metadata: CKShareMetadata){
let operation = CKAcceptSharesOperation(shareMetadatas: [metadata])
operation.acceptSharesCompletionBlock = { error in
if let error = error{
print("accept share error: \(error)")
}else{
//Share accepted!
}
}
CKContainer.default().add(operation)
}
I think there are easier ways to work through this using NSItemProvider and NSSharingService, but I'm doing a lot of custom UI and wanted to have full control of the share workflow.
I hope this helps someone. :)
I've created an ASP.NET Core web api which I am running locally in visual studio, I am able to browse to this in Safari and tested the API using postman.
When I use the following swift code in my MacOS app:
let url = URL(string: "http://localhost:5000/api/values")
let task = URLSession.shared.dataTask(with: url!) { data, response, error in
guard error == nil else {
print(error!)
return
}
guard let data = data else {
print("Data is empty")
return
}
let json = try! JSONSerialization.jsonObject(with: data, options: [])
print(json)
}
task.resume()
It always fails with error
NSLocalizedDescription=A server with the specified hostname could not
be found.
Do I have to change some settings so that my app can make Http requests to the API?
Thanks
You probably already figured out a solution or a way around the problem, but since I reached the same question when having this problem I will provide my answer anyway in case anyone else finds this question.
For me the problem was that the MacOS app was not allowed to connect to the internet since it was automatically running in an app sandbox. The solution was to add "Outgoing Connections" to the app capabilities. See screenshot below.