I am trying to call ChatGPT api in firebase cloud function with app check validation. I want to use “App Attest” as validation method. I have done all the setup and coding as mentioned in the Firebase app check doc but still I am getting invalid app check token error.
Here is what I have tried:
Physical device
-
Entitlement
Set App Attest Env to “production” -
Added App Attest in capability
(https://i.stack.imgur.com/b07wz.png) -
Enabled App Attest in Firebase console after adding Apple team id
(https://i.stack.imgur.com/IgeuU.png) -
Configuration code in App Delegate
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
let providerFactory = YourAppCheckProviderFactory()
// let providerFactory = AppCheckDebugProviderFactory()
AppCheck.setAppCheckProviderFactory(providerFactory)
FirebaseApp.configure()
return true
}
}
class YourAppCheckProviderFactory: NSObject, AppCheckProviderFactory {
func createProvider(with app: FirebaseApp) -> AppCheckProvider? {
return AppAttestProvider(app: app)
// return DeviceCheckProvider(app: app)
}
}
- Here is my Firebase function which I am trying to call from swift and which subsequently calls ChatGPT API upon successful validation of app check token
exports.callGPT = functions.https.onRequest(async (request, response) => {
try {
// Validate Firebase App Check token
const appCheckToken = request.headers["x-firebase-appcheck"];
if (!appCheckToken) {
return response.status(401)
.send("Unauthorized: App Check token missing");
}
// const appCheckResponse = await getAppCheck().verifyToken(appCheckToken);
const appCheckResponse = await admin.appCheck()
.verifyToken(appCheckToken);
if (!appCheckResponse.valid) {
return response.status(401)
.send("Unauthorized: Invalid App Check token");
}
// Replace "YOUR_CHATGPT_API_KEY" with your actual ChatGPT API key
const chatGPTApiKey = "sk-token";
// Extract the input text from the request body
// const inputText = "Hi";
const inputText = request.body.text;
// Make a request to the ChatGPT API
const chatGPTResponse = await axios.post(
"https://api.openai.com/v1/chat/completions",
{
model: "gpt-3.5-turbo",
messages: [{role: "system", content: "You are a helpful assistant."},
{role: "user", content: inputText}],
},
{
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer " + chatGPTApiKey,
},
},
);
// Extract the response from ChatGPT
const chatGPTOutput = chatGPTResponse.data.choices[0].message.content;
// Send the ChatGPT output as the response
response.status(200).send({output: chatGPTOutput});
} catch (error) {
console.error("Error calling ChatGPT API:", error);
response.status(500).send("Internal Server Error");
}
});
- This is my swift code which calls cloud function
func sendPrompt() async {
showLoader = true
AppCheck.appCheck().token(forcingRefresh: false) { token, error in
if let token = token {
guard let url = URL(string: "baseurl/callGPT") else {
return
}
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue(token.token, forHTTPHeaderField: "X-Firebase-AppCheck")
struct RequestObj: Codable, Hashable{
var text: String?
}
var requestObj = RequestObj(text: topic)
let scriptData = try? JSONEncoder().encode(requestObj)
request.httpBody = scriptData
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
if let error = error {
print("Error in app script: \(error)")
} else if let data = data, let responseString = String(data: data, encoding: .utf8) {
print("responseString = \(responseString)")
do {
struct ResponseObj: Codable, Hashable{
var output:String?
}
var responseObj = try JSONDecoder().decode(ResponseObj.self, from: data)
output = responseObj.output ?? ""
print("output = \(output)")
} catch {
print("an error occurred", error)
}
}
showLoader = false
}
task.resume()
} else if let error = error {
print ("AppCheck error: \(error as NSError).userInfo)")
}
}
}
I have tried to run on my physical device but it gives “invalid app check token” error.
I also tried to run on Xcode simulator after doing the following changes
Xcode simulator
- in App Delegate
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
// let providerFactory = YourAppCheckProviderFactory()
let providerFactory = AppCheckDebugProviderFactory()
AppCheck.setAppCheckProviderFactory(providerFactory)
FirebaseApp.configure()
return true
}
}
class YourAppCheckProviderFactory: NSObject, AppCheckProviderFactory {
func createProvider(with app: FirebaseApp) -> AppCheckProvider? {
return AppAttestProvider(app: app)
// return DeviceCheckProvider(app: app)
}
}
-
Added -FIRDebugEnabled in the Arguments Passed on Launch section
(https://i.stack.imgur.com/P5f3O.png) -
Added debug token in firebase console
(https://i.stack.imgur.com/bp7nd.png)
Kept code in point 5 & 6 same as above. Even after doing all the required changes I am not able to validate my app check token in cloud function




