I'm writing an ImageRecognizer using Firebase Cloud Functions API in Xcode 12.4 with Swift as follows:
import Firebase
import UIKit
import Foundation
class ImageRecognizer {
let imageName: String
lazy var functions = Functions.functions()
init(imageName: String) {
self.imageName = imageName
}
func recognize() {
print("RECOGNIZING")
if let userImage = UIImage(named: imageName) {
print("IMAGE VALID")
guard let imageData = userImage.jpegData(compressionQuality: 1.0) else { return }
print("IMAGE DATA VALID")
let base64encodedImage = imageData.base64EncodedString()
let requestData = [
"image": ["content": base64encodedImage],
"features": ["type": "TEXT_DETECTION"],
"imageContext": ["languageHints": ["sa"]]
]
functions.httpsCallable("annotateImage").call(requestData) { (result, error) in
if let error = error as NSError? {
if error.domain == FunctionsErrorDomain {
let code = FunctionsErrorCode(rawValue: error.code)
let message = error.localizedDescription
let details = error.userInfo[FunctionsErrorDetailsKey]
print("ERROR \(message), CODE \(code), DETAILS \(details)")
}
print("RESULT \(result)")
}
guard let annotation = (result?.data as? [String: Any])?["fullTextAnnotation"] as? [String: Any] else { return }
print("%nComplete annotation:")
let text = annotation["text"] as? String ?? ""
print("%n\(text)")
}
}
}
}
My cloud function in index.js is as follows:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.annotateImage = void 0;
const functions = require("firebase-functions");
const vision_1 = require("@google-cloud/vision");
const client = new vision_1.default.ImageAnnotatorClient();
// This will allow only requests with an auth token to access the Vision
// API, including anonymous ones.
// It is highly recommended to limit access only to signed-in users. This may
// be done by adding the following condition to the if statement:
// || context.auth.token?.firebase?.sign_in_provider === 'anonymous'
//
// For more fine-grained control, you may add additional failure checks, ie:
// || context.auth.token?.firebase?.email_verified === false
// Also see: https://firebase.google.com/docs/auth/admin/custom-claims
exports.annotateImage = functions.https.onCall(async (data, context) => {
console.log("DATA: " + data);
if (!context.auth) {
throw new functions.https.HttpsError("unauthenticated", "annotateImage must be called while authenticated.");
}
try {
return await client.annotateImage(JSON.parse(data));
}
catch (e) {
throw new functions.https.HttpsError("internal", e.message, e.details);
}
});
The JSON.parse(data) part does not work - it returns the error:
RECOGNIZING IMAGE VALID IMAGE DATA VALID 2021-03-13 07:57:37.915895+0530 ImageReader[10575:10270760] [] nw_protocol_get_quic_image_block_invoke dlopen libquic failed ERROR Unexpected token o in JSON at position 1, CODE Optional(__C.FIRFunctionsErrorCode), DETAILS nil RESULT nil
Even when I change to any other dictionary as my requestData, still the JSON doesn't go through. Does anyone know how to call Firebase cloud functions properly from iOS?