title: Firebase cloud function triggers FCM but Request is missing required authentication credential
body: <p>I am trying to use firebase-admin inside a firebase cloud function to send a message via firebase cloud messaging (FCM).</p>
  
  <p>When reading through the <a href="https://firebase.google.com/docs/cloud-messaging/admin/send-messages?authuser=0" rel="nofollow noreferrer">documentation</a> it says</p>
  
  <blockquote>
    <p>To use the Admin FCM API, you must first follow the steps in Add the Firebase Admin SDK to your Server.</p>
  </blockquote>
  
  <p>But I think this is not required since I'm only using cloud functions?</p>
  
  <p>Anyway, it all works up until the point of <code>admin.messaging().send</code> where I get this error:</p>
  
  <pre><code>Error sending message: { Error: Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.
      at FirebaseMessagingError.Error (native)
      at FirebaseMessagingError.FirebaseError [as constructor] (/user_code/node_modules/firebase-admin/lib/utils/error.js:39:28)
      at FirebaseMessagingError.PrefixedFirebaseError [as constructor] (/user_code/node_modules/firebase-admin/lib/utils/error.js:85:28)
      at new FirebaseMessagingError (/user_code/node_modules/firebase-admin/lib/utils/error.js:241:16)
      at Function.FirebaseMessagingError.fromServerError (/user_code/node_modules/firebase-admin/lib/utils/error.js:271:16)
      at FirebaseMessagingRequestHandler.handleHttpError (/user_code/node_modules/firebase-admin/lib/messaging/messaging-api-request.js:125:50)
      at /user_code/node_modules/firebase-admin/lib/messaging/messaging-api-request.js:113:23
      at process._tickDomainCallback (internal/process/next_tick.js:135:7)
    errorInfo: 
     { code: 'messaging/invalid-apns-credentials',
       message: 'Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.' },
    codePrefix: 'messaging' }
  </code></pre>
  
  <p>This is my source code of the cloud function</p>
  
  <pre><code>import * as functions from 'firebase-functions'
  import * as admin from 'firebase-admin'
  
  admin.initializeApp(functions.config().firebase)
  const firestore = admin.firestore()
  firestore.settings({timestampsInSnapshots: true})
  
  exports.notification = functions.firestore
    .document(path)
    .onUpdate(async (change, context) =&gt; {
      const deviceTokens = ['deviceToken-123123123']
      deviceTokens.forEach(token =&gt; {
        const fcmMessage = {
          notification: {title: 'test title', body: 'test body'},
          token
        }
        admin.messaging().send(fcmMessage)
          .then((response) =&gt; {
            // Response is a message ID string.
            console.log('Successfully sent message:', response)
          })
          .catch((error) =&gt; {
            console.log('Error sending message:', error)
          })
      })
    })
  </code></pre>
  
  <p>The device tokens are stored in firestore and retrieved from firestore inside this cloud function as well. The format of the device token is correct. I have replaced it with a placeholder for this example.</p>
  
  <p>I also looked around for similar questions, but the only one I could find was <a href="https://stackoverflow.com/questions/51589076/cloud-functions-fcm-expected-oauth-2-access-token">this one</a></p>