جاوااسکریپت - خطا در دریافت توکن دسترسی: خطا هنگام ارسال درخواست: getaddrinfo ENOTFOUND metadata.google.internal. آیا این خطا گاهی رخ میدهد؟


برای مقدمه، این خطا است.

Promise { <pending> }
nodejsproject\node_modules\firebase-admin\lib\utils\error.js:44
        var _this = _super.call(this, errorInfo.message) || this;
                           ^
FirebaseAppError: Credential implementation provided to initializeApp() via the "credential" property failed to fetch a valid Google OAuth2 access token with the following error: "Error fetching access token: Error while making request: getaddrinfo ENOTFOUND metadata.google.internal. Error code: ENOTFOUND".
    
  errorInfo: {
    code: 'app/invalid-credential',
    message: 'Credential implementation provided to initializeApp() via the "credential" property failed to fetch a valid Google OAuth2 access token with the following error: "Error fetching access token: Error while making request: getaddrinfo ENOTFOUND metadata.google.internal. Error code: ENOTFOUND".'
  },
  codePrefix: 'app'
}

از آنچه من متوجه شدم، این خطا به این دلیل است که پارامترهای من نامعتبر هستند یا چیزی باعث راهاندازی نادرست فایربیس شده است.

حالا دارم برنامه را به این صورت راهاندازی میکنم: initializeApp();.

پس مقداردهی اولیه کار میکند. وقتی من دستوری مانند const userInfo=await getAuth().verifyIdToken(authorization); اجرا میکنم، دستور کار میکند و من userInfo را دریافت میکنم، اما وقتی دستوری مانند const userInfo=await getAuth().getUser(uuid); اجرا میکنم، شکست میخورد.

تا جایی که میدانم، نحو درست است و نحوه استفاده من از متدها هم درست است. فقط مطمئن نیستم چرا وقتی از یک متد استفاده میکنم خطای initializeApp میگیرم اما هنگام استفاده از متد دیگری نه.

پاسخ شماره ۱

من فهمیدم چگونه هر دو تابع را بدون ایجاد خطا کار کنم. برای حل مشکلم، متغیرهای محیطیام را تغییر دادم.

قبلاً من داشتم:

GCLOUD_PROJECT="project-name"
FIREBASE_CONFIG={keyDetailsHere}

بعد، آن را تغییر میدهم به جایی که مقدار مسیر کلید حساب سرویس باشد:

GOOGLE_APPLICATION_CREDENTIALS="C:\Users\username\Downloads\service-account-file.json"

من مطمئن نیستم چرا نسخه اصلی روی برخی توابع کار میکرد (بهویژه getAuth().verifyIdToken()) اما روی بقیه شکست میخورد. تا جایی که من فهمیدهام، initializeApp() اگر خالی گذاشته شود، به دنبال متغیر محیطی GOOGLE_APPLICATION_CREDENTIALS میگردد. اگر آن را پیدا کند، از اعتبارنامههایی که بهصورت واضح تعیین کردهاید استفاده میکند، در غیر این صورت از اعتبارنامههای پیشفرض برنامه گوگل استفاده میکند. پس از راهاندازی با اعتبارنامههای پیشفرض برنامه گوگل، به متغیر محیطی FIREBASE_CONFIG برای گزینههای راهاندازی نگاه میکند.

گزیدهای از مستندات: «چون جستجوی پیشفرض اعتبارنامهها در محیطهای گوگل به طور کامل خودکار است و نیازی به ارائه متغیرهای محیطی یا پیکربندی دیگر نیست، این روش برای راهاندازی SDK به شدت برای برنامههایی که روی Compute Engine، Kubernetes Engine، App Engine و Cloud Functions اجرا میشوند توصیه میشود.»

درک من این است که راهاندازی اولیه من کار نکرد زیرا من به صورت محلی توسعه میدهم و نه در یک محیط گوگل، بنابراین نمیتوانست یک اعتبار پیشفرض مناسب برنامه گوگل را دریافت کند.

برای مرجع، اینها اسناد هستند: LINK

پاسخ شماره ۲

در این خطا دلیل آن پیادهسازی گواهینامه JSON یا عدم وارد کردن صحیح آن است

فایل JSON فایربیس وارد نشده یا توکن applicationDefault() منقضی شده است، بنابراین اکنون فایل JSON FCM خود را وارد کنید.

این مرحله را دنبال کنید ->

import json from "your-jsonfile-028f728f9457.json" assert { type: "json" };

یا

import fs from "fs";

let jsonData = JSON.parse(
  fs.readFileSync("./your-jsonfile-028f728f9457.json", "utf-8")
);

در این jsonData برای استفاده از مدارک خود

admin.initializeApp({
  credential: admin.credential.cert(jsonData),
  projectId: "fcm=project-id",
});