2

I have a firebase cloud function written in node.js which is called from a custom swift class but when I try to execute the cloud function I don't get the link token back, just nil. Here is my cloud function:

// PLAID
const plaid = require('plaid');

exports.createPlaidLinkToken = functions.https.onCall(async (data, context) => {

  const customerId = context.auth.uid

  const plaidClient = new plaid.Client({
    clientID: functions.config().plaid.client_id,
    secret: functions.config().plaid.secret,
    env: plaid.environments.sandbox,
    options: {
      version: '2019-05-29'
    }
  })

  return plaidClient.createLinkToken({
    user: {
      client_user_id: customerId
    },
    client_name: 'Bon Voyage',
    products: ['auth'],
    country_codes: ['US'],
    language: 'en'
  })
  .then((apiResponse) => {
    const linkToken = apiResponse.link_token
    return linkToken
  })
  .catch((err) => {
    functions.logger.log(err)
    throw new functions.https.HttpsError('internal', 'Unable to create plaid link token: ' + err)
  })
})

and here is my custom swift class:

class PlaidApi {
    
    class func createLinkToken(completion: @escaping (String?) -> () ) {
        Functions.functions().httpsCallable("createPlaidLinkToken").call { (result, error) in
            if let error = error {
                debugPrint("Got here 1: \(error.localizedDescription)")
                return completion(nil)
            }
            guard let linkToken = result?.data as? String else { print("Got here 2"); return completion(nil) }

            completion(linkToken)
        }
    }
}

here is where is call the class function:

    @IBAction func userIconClicked(_ sender: Any) {
        
        let userActionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
        
        let logOut = UIAlertAction(title: "Log Out", style: .default) { (action) in
            
            // Logout
            do {
                try Auth.auth().signOut()
                print("DEBUG: got here")
            } catch {
                print("DEBUG: \(error.localizedDescription)")
            }
        }
    
        
        let manageCreditCards = UIAlertAction(title: "Manage Credit Cards", style: .default) { (action) in
            // Display Stripe Widget
            self.paymentContext.pushPaymentOptionsViewController()
        }
        
        let manageBankAccounts = UIAlertAction(title: "Manage Bank Accounts", style: .default) { (action) in
            // Display Bank Accounts
            PlaidApi.createLinkToken { linkToken in
                print(linkToken)
            }
        }
        
        let closeAlertAction = UIAlertAction(title: "Close", style: .cancel)
        
        userActionSheet.addAction(logOut)
        userActionSheet.addAction(manageCreditCards)
        userActionSheet.addAction(manageBankAccounts)
        userActionSheet.addAction(closeAlertAction)
        
        present(userActionSheet, animated: true)
    }

As I said I only get the error message "Got here 1: The data couldn't be read because it isn't in the correct format." nil printed out in the Xcode debugger window.

Stephen501
  • 153
  • 8

1 Answers1

0

Got it working! I was using the wrong Xcode environment in my project. I have a production environment and a development environment. I was using the production environment instead of the development environment. So my swift code was trying to invoke a cloud function in the production firebase cloud functions which only existed in the development firebase cloud functions.

Stephen501
  • 153
  • 8