I'm receiving a pdf as base64 string, then I want to save that into Firebase storage bucket. So to my knowledge the process is:
- put binary data into base64 string
- make base64 string into data
but I'm getting nil when trying to convert the string into Data (note that I'm actually getting data from the response, but when converting to data in swift from a base64 string I get nil...)
is there a special syntax to convert base64 to Data so I can save the pdf into firebase?
Swift function
func getAssetReportPDF(){
self.hasLoaded = false;
let json: [String: Any] = [
"assetReportToken": UserDefaults.standard.value(forKey: "asset_report_token") as! String
]
Functions.functions().httpsCallable("getAssetReportPdf").call(json) { (result, error) in
if let error = error {
debugPrint(error.localizedDescription)
return
}
let result = result?.data as! String
print(result)
//convert the string base64 into Data
let dataPDF = Data(base64Encoded: result)
//let dataPDF = Data(base64Encoded: result!.data)
//let dataPDF = NSData(base64Encoded: result?.data, options: NSData.Base64DecodingOptions.ignoreUnknownCharacters) as Data?
//write it in firebase bucket(PDF)
let storage = Storage.storage()
//let user = UserService.shared.user
let uploadMetaData = StorageMetadata()
uploadMetaData.contentType = "application/pdf"
//create unique file name using phone number
let documentID = UserDefaults.standard.string(forKey: "phone")
//SAVE pdf TO STORAGE
///reference to storage root, bucket is userDocument id, then files are photo uploaded with a unique id
let storageRef = storage.reference().child(documentID!).child(documentID!)
let uploadTask = storageRef.putData(dataPDF!, metadata: uploadMetaData){
(_, err) in
if let err = err {
print("an error has occurred - \(err.localizedDescription)")
} else {
print("pdf uploaded successfully")
///SAVE pdf URL AS REFERENCE IN USER COLLECTION
let db = Firestore.firestore()
let ref = db.collection("users").document(documentID!)
//download URL of the pic just posted
storageRef.downloadURL { url, error in
ref.setData(["asset_report": url!.absoluteString ], merge: true) { err in
if let err = err {
print("Error writing pdf url: \(err)")
} else {
print("url successfully saved!")
}
}
}
}
}
//save the report id in firebase and the pdf as well
}
}
cloud function in node.js
exports.getAssetReportPdf = functions.https.onCall(async (data, context) => {
const assetReportToken = data.assetReportToken;
const configuration = new Configuration({
basePath: PlaidEnvironments[functions.config().app.env],
baseOptions: {
headers: {
"PLAID-CLIENT-ID": functions.config().plaid.client_id,
"PLAID-SECRET": functions.config().plaid.secret,
},
},
});
const plaidClient = new PlaidApi(configuration);
return plaidClient
.assetReportPdfGet({
asset_report_token: assetReportToken
})
.then((response) => {
//prettyPrintResponse(response);
//const pdf = response.buffer.toString('base64');
const pdf = response.data.toString('base64');
return pdf; //I need to save it in FIREBASE stack
})
.catch((err) => {
console.log(err);
throw new functions.https.HttpsError(
"internal",
"Unable to download pdf " err
);
});
});
CodePudding user response:
Can you try like this, first you create PDF file then verify that the received base64
string got converted into pdf or not. Then, you can upload the file to Firebase
, once it is uploaded you can delete
the same file from the Documents
directory.
/// This will creates a PDF file
func createPDF(with base64Info: String) {
let base64Data = Data(base64Encoded: base64Info, options: .ignoreUnknownCharacters)
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let filePath = "\(documentsPath)/{your_pdf_filename}.pdf"
if FileManager.default.fileExists(atPath: filePath) {
let url = URL(fileURLWithPath: filePath)
do{
try base64Data?.write(to: url, options: .atomic)
}catch let failedError {
print("Failed to write the pdf data due to \(failedError.localizedDescription)")
}
}else{
print("Failed to write the pdf data")
}
}
/// Verify your created PDF file
func verifyPDF() {
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let filePath = "\(documentsPath)/{your_pdf_filename}.pdf"
let url = URL(fileURLWithPath: filePath)
let webView = WKWebView()
webView.load(URLRequest(url: url))
}
CodePudding user response:
I was missing to specify responseType: 'arraybuffer' in my cloud function
return plaidClient
.assetReportPdfGet({
asset_report_token: assetReportToken
},
{
responseType: 'arraybuffer',
})
.then((response) => {
const pdf = response.data.toString('base64');
return pdf;
})
.catch((err) => {
console.log(err);
throw new functions.https.HttpsError(
"internal",
"Unable to download pdf " err
);
});
});