שגיאות Admin SDK מחולקות לשתי קטגוריות:
- שגיאות תכנות: אלו הן שגיאות תכנות ותצורה באפליקציית המשתמש. הם מתרחשים בעיקר עקב שימוש שגוי ב-SDK (כגון העברת
null
לשיטה שאינה מקבלת ערכיnull
), ושגיאות תצורה אחרות ברמת פרויקט Firebase או SDK (חסרים אישורים, מחרוזת מזהה פרויקט שגויה וכדומה עַל). - שגיאות API: אלה כוללות שגיאות שונות הניתנות לשחזור המתרחשות ביישום SDK, כל השגיאות שמקורן בשירותי Firebase backend ושגיאות חולפות אחרות (כגון פסקי זמן) שעלולות להתרחש בעת ביצוע קריאות RPC.
ה-Admin SDK מאותת על שגיאות תכנות על ידי זריקת שגיאה מקורית לפלטפורמה המדוברת.
- Java: זורק מופעים של
IllegalArgumentException
,NullPointerException
או סוג שגיאת זמן ריצה מובנה דומה. - Python: מעלה מופעים של
ValueError
,TypeError
או סוג שגיאה מובנה אחר. - Go: מחזירה שגיאה כללית.
- .NET: זורק מופעים של
ArgumentException
,ArgumentNullException
או סוג שגיאה מובנה דומה.
ברוב המצבים אסור לטפל במפורש בשגיאות תכנות. במקום זאת, עליך לתקן את הקוד והתצורה שלך כדי למנוע שגיאות תכנות לחלוטין. שקול את קטע ה-Java הבא:
String uid = getUserInput();
UserRecord user = FirebaseAuth.getInstance().getUser(uid);
אם השיטה getUserInput()
מחזירה מחרוזות null
או ריקות, ה-API FirebaseAuth.getUser()
זורק קובץ IllegalArgumentException
. במקום לטפל בה באופן מפורש, אתה יכול להקל על הבעיה על ידי הבטחת השיטה getUserInput()
לעולם לא תחזיר מחרוזת UID לא חוקית. אם זה לא אפשרי, יישם את בדיקת הארגומנטים הדרושים בקוד משלך באופן הבא:
String uid = getUserInput();
if (Strings.isNullOrEmpty(uid)) {
log.warn("UID must not be null or empty");
return;
}
UserRecord user = FirebaseAuth.getInstance().getUser(uid);
כעיקרון, לעולם אל תנסה שוב על שגיאות תכנות. מתן אפשרות לסמנטיקה מהירה לכישלון על שגיאות תכנות היא לרוב דרך הפעולה הטובה ביותר מכיוון שהיא חושפת באגים בתכנות ושגיאות תצורה במהלך הפיתוח, שם ניתן לתקן אותן באופן מיידי. כשל מהיר בהקשר זה יכול להיות מתן אפשרות לשגיאות להתפשט למטפל שגיאות גלובלי באפליקציה שלך, או פשוט רישום אותן למטרות ביקורת ולאחר מכן סיום זרימת הביצוע הנוכחית (האפליקציה לא צריכה לקרוס). באופן כללי, עקוב אחר השיטות המומלצות לטיפול בשגיאות של שפת התכנות שלך ושל מסגרת היישום. לעתים קרובות זה לבד מספיק כדי להתמודד בצורה נכונה עם סוג זה של שגיאות.
בדרך כלל, עיקר מאמצי הטיפול בשגיאות יתמקדו בטיפול בשגיאות API . חלק מהשגיאות הללו ניתנות לשחזור, כגון שגיאות שנבעו משירות בלתי זמין באופן זמני, וחלקן אף צפויות במהלך זרימת ההפעלה הרגילה של התוכנית, כגון זיהוי אסימוני מזהה לא חוקיים או שפג תוקפם. שאר המדריך מתאר כיצד ה-Admin SDK מייצג שגיאות API כאלה, ואת האפשרויות השונות הזמינות לטיפול בהן.
מבנה של שגיאת API
שגיאת API מורכבת מהרכיבים הבאים:
- קוד שגיאה
- הודעת שגיאה
- קוד שגיאה בשירות (אופציונלי)
- תגובת HTTP (אופציונלי)
מובטח שכל שגיאת API תכיל קוד שגיאה והודעת שגיאה. שגיאות API מסוימות מכילות גם קוד שגיאת שירות הספציפי ל-API שיצר את השגיאה. לדוגמה, שגיאות מסוימות שנוצרו על ידי Firebase Auth API מכילות קוד שגיאת שירות הספציפי ל-Firebase Auth. אם השגיאה הייתה תוצאה של תגובת שגיאת HTTP משירות אחורי, שגיאת ה-API מכילה גם את תגובת ה-HTTP המתאימה. זה יכול לשמש כדי לבדוק את הכותרות והתוכן המדויקים של התגובה המקורית, וזה שימושי עבור ניפוי באגים, רישום, או יישום לוגיקה מתוחכמת יותר לטיפול בשגיאות.
כל ההטמעות של Admin SDK מלבד Node.js מספקות ממשקי API המאפשרים גישה לרכיבים שלעיל של שגיאות API.
סוגי שגיאות וממשקי API לפי שפה
Java
ב-Java כל שגיאות ה-API מרחיבות את המחלקה FirebaseException
. אתה יכול לגשת לקוד השגיאה, להודעת השגיאה ולתגובת ה-HTTP האופציונלית ממחלקת הבסיס הזו.
public class FirebaseException extends Exception {
@NonNull
public ErrorCode getErrorCode() {
// ...
}
@NonNull
public String getMessage() {
// ...
}
@Nullable
public IncomingHttpResponse getHttpResponse() {
// ...
}
}
ממשקי API שחושפים קודי שגיאות שירות מספקים תת-מחלקות ספציפיות ל-API של FirebaseException
. לדוגמה, כל השיטות הציבוריות בממשק ה-API FirebaseAuth
מוכרזות כמזרקות מופעים של FirebaseAuthException
. אתה יכול לגשת לקוד שגיאת השירות ממחלקה נגזרת זו.
public class FirebaseAuthException extends FirebaseException {
@Nullable
public AuthErrorCode getAuthErrorCode() {
// ...
}
}
פִּיתוֹן
ב-Python כל שגיאות ה-API מרחיבות את המחלקה exceptions.FirebaseError
. אתה יכול לגשת לקוד השגיאה, להודעת השגיאה ולתגובת HTTP האופציונלית ממחלקת הבסיס הזו.
class FirebaseError(Exception):
@property
def code(self):
# ...
@property
def message(self):
# ...
@property
def http_response(self):
# ...
יתר על כן, Python Admin SDK מציע מחלקות נגזרות נפרדות עבור כל קוד שגיאה. אנו מתייחסים אליהם כאל מחלקות שגיאות פלטפורמה .
class InvalidArgumentError(FirebaseError):
# ...
class NotFoundError(FirebaseError):
# ...
אתה יכול לתפוס FirebaseError
בקוד שלך ולבדוק code
שלו, או לבצע בדיקת isinstance()
מול מחלקת שגיאות של פלטפורמה. או שאתה יכול לכתוב קוד כדי לתפוס ישירות סוגי שגיאות ספציפיים בפלטפורמה. הגישה האחרונה צפויה לגרום לקוד טיפול בשגיאות קריא יותר.
ממשקי API החושפים קודי שגיאה של שירות מספקים תת-מחלקות ספציפיות ל-API של מחלקות שגיאות בפלטפורמה. לדוגמה, כל השיטות הציבוריות במודול auth
עשויות לזרוק סוגי שגיאות ספציפיות ל-API כגון auth.UserNotFoundError
ו- auth.ExpiredIdTokenError
.
class UserNotFoundError(exceptions.NotFoundError):
# …
class ExpiredIdTokenError(exceptions.InvalidArgumentError):
# ...
ללכת
ה- Go Admin SDK מספק חבילת errorutils
המכילה סדרה של פונקציות המאפשרות בדיקת קודי שגיאה.
package errorutils
func IsInvalidArgument(err error) bool {
// ...
}
func IsNotFound(err error) bool {
// ...
}
הודעת השגיאה היא פשוט המחרוזת המוחזרת על ידי הפונקציה Error()
של שגיאה. ניתן לגשת לתגובת HTTP האופציונלית על ידי קריאה לפונקציה errorutils.HTTPResponse()
, המחזירה *http.Response
.
זה בטוח להעביר nil
או כל ערך שגיאה אחר לפונקציות בדיקת השגיאות בחבילת errorutils
. הם מחזירים true
אם ארגומנט הקלט מכיל את קוד השגיאה המדובר, ומחזירים false
עבור כל השאר. לפונקציה HTTPResponse()
יש התנהגות דומה, אלא שהיא מחזירה nil
במקום false
.
ממשקי API החושפים קודי שגיאות שירות מספקים פונקציות בדיקת שגיאות ספציפיות ל-API בחבילות המתאימות. לדוגמה, חבילת ה- auth
מספקת את הפונקציות IsUserNotFound()
ו- IsExpiredIDTokenError()
.
.נֶטוֹ
ב-.NET כל שגיאות ה-API מרחיבות את המחלקה FirebaseException
. אתה יכול לגשת לקוד השגיאה של הפלטפורמה, להודעת השגיאה ולתגובת ה-HTTP האופציונלית ממחלקת הבסיס הזו.
public class FirebaseException : Exception {
public ErrorCode ErrorCode { get; }
public String Message { get; }
public HttpResponseMessage HttpResponse { get; }
}
ממשקי API שחושפים קודי שגיאות שירות מספקים תת-מחלקות ספציפיות ל-API של FirebaseException
. לדוגמה, כל השיטות הציבוריות בממשק ה-API FirebaseAuth
מוכרזות כמזרקות מופעים של FirebaseAuthException
. אתה יכול לגשת לקוד שגיאת השירות ממחלקה נגזרת זו.
public class FirebaseAuthException : FirebaseException {
public AuthErrorCode AuthErrorCode { get; }
}
קודי שגיאה של פלטפורמה
קודי שגיאה נפוצים בכל שירותי Firebase ו-Google Cloud Platform. הטבלה הבאה מתארת את כל קודי השגיאה האפשריים של הפלטפורמה. זוהי רשימה יציבה, וצפויה להישאר ללא שינוי לתקופה ארוכה.
INVALID_ARGUMENT | הלקוח ציין ארגומנט לא חוקי. |
FAILED_PRECONDITION | לא ניתן לבצע בקשה במצב המערכת הנוכחי, כגון מחיקת ספרייה לא ריקה. |
מחוץ לטווח | הלקוח ציין טווח לא חוקי. |
לא מאומת | הבקשה לא אומתה עקב אסימון OAuth חסר, לא חוקי או שפג תוקפו. |
ההרשאה נדחתה | ללקוח אין הרשאה מספקת. זה יכול לקרות מכיוון שלאסימון OAuth אין את ההיקפים הנכונים, ללקוח אין הרשאה או שה-API לא הופעל עבור פרויקט הלקוח. |
לא נמצא | המשאב שצוין לא נמצא, או שהבקשה נדחתה מסיבות לא ידועות כמו רישום הלבן. |
סְתִירָה | התנגשות במקביל, כגון התנגשות קריאה-שינוי-כתיבה. בשימוש רק על ידי כמה שירותים מדור קודם. רוב השירותים משתמשים ב-ABORTED או ALREADY_EXISTS במקום זה. עיין בתיעוד הספציפי לשירות כדי לראות באיזה מהם לטפל בקוד שלך. |
הופסק | התנגשות במקביל, כגון התנגשות קריאה-שינוי-כתיבה. |
כבר קיים | המשאב שלקוח ניסה ליצור כבר קיים. |
RESOURCE_EXHAUSTED | או מחוץ למכסת המשאבים או הגעה להגבלת שיעור. |
מבוטל | הבקשה בוטלה על ידי הלקוח. |
DATA_LOSS | אובדן נתונים בלתי ניתן לשחזור או השחתת נתונים. על הלקוח לדווח למשתמש על השגיאה. |
לא ידוע | שגיאת שרת לא ידועה. בדרך כלל באג בשרת. קוד שגיאה זה מוקצה גם לשגיאות ניתוח (unmarshal) של תגובה מקומית, ולמגוון רחב של שגיאות I/O ברמה נמוכה אחרות שאינן ניתנות לאבחון בקלות. |
פְּנִימִי | שגיאת שרת פנימית. בדרך כלל באג בשרת. |
אינו זמין | שירותים לא זמינים. בדרך כלל השרת מושבת זמנית. קוד שגיאה זה מוקצה גם לשגיאות רשת מקומית (החיבור נדחה, אין נתיב למארח). |
DEADLINE_EXCEEDED | חרג המועד האחרון לבקשה. זה יקרה רק אם המתקשר יגדיר דד-ליין קצר יותר ממועד ברירת המחדל של יעד API (כלומר דד-ליין מבוקש אינו מספיק כדי שהשרת יעבד את הבקשה), והבקשה לא הסתיימה בתוך המועד. קוד שגיאה זה מוקצה גם לזמן קצוב לחיבור מקומי ולקריאה. |
רוב ממשקי ה-API יכולים לגרום רק לקבוצת משנה של קודי השגיאה שלעיל. בכל מקרה, לא מצפים ממך לטפל במפורש בכל קודי השגיאה הללו בעת יישום מטפלי השגיאות שלך. רוב היישומים יתעניינו רק ב-1-2 קודי שגיאה ספציפיים ויתייחסו לכל השאר כאל כישלון גנרי שלא ניתן לשחזר.
קודי שגיאה ספציפיים לשירות
אישור Firebase
CERTIFICATE_FETCH_FAILED | נכשל באחזור אישורי מפתח ציבורי הנדרשים לאימות JWT (אסימון מזהה או קובץ cookie של הפעלה). |
האימייל כבר קיים | משתמש כבר קיים עם האימייל שסופק. |
EXPIRED_ID_TOKEN | פג תוקפו של אסימון המזהה שצוין ל- verifyIdToken() . |
EXPIRED_SESSION_COOKIE | פג תוקף קובץ ה-cookie של ההפעלה שצוין ל- verifySessionCookie() i. |
INVALID_DYNAMIC_LINK_DOMAIN | תחום הקישור הדינמי שסופק אינו מוגדר או מורשה עבור הפרויקט הנוכחי. קשור לממשקי API של קישור פעולות בדוא"ל. |
INVALID_ID_TOKEN | אסימון המזהה שצוין ל- verifyIdToken() אינו חוקי. |
INVALID_SESSION_COOKIE | קובץ ה-cookie של ההפעלה שצוין ל- verifySessionCookie() אינו חוקי. |
PHONE_NUMBER_ALREADY_EXISTS | משתמש כבר קיים עם מספר הטלפון שסופק. |
REVOKED_ID_TOKEN | אסימון המזהה שצוין ל- verifyIdToken() בוטל. |
REVOKED_SESSION_COOKIE | פג תוקף קובץ ה-cookie של ההפעלה שצוין ל- verifySessionCookie() . |
UNAUTHORIZED_CONTINUE_URL | הדומיין של המשך כתובת האתר אינו ברשימת ההיתרים. קשור לממשקי API של קישור פעולות בדוא"ל. |
המשתמש לא נמצא | לא נמצאה רשומת משתמש עבור המזהה הנתון. |
Firebase Cloud Messaging
THIRD_PARTY_AUTH_ERROR | אישור ה-APN או מפתח ה-API של דחיפה באינטרנט לא היה חוקי או חסר. |
INVALID_ARGUMENT | ארגומנט אחד או יותר שצוין בבקשה לא היה חוקי. |
פְּנִימִי | שגיאת שרת פנימית. |
חריגה מהמכסה | חרגת ממגבלת השליחה עבור יעד ההודעה. |
SENDER_ID_MISMATCH | מזהה השולח המאומת שונה מזהה השולח עבור אסימון הרישום. זה בדרך כלל אומר שהשולח ואסימון הרישום היעד אינם נמצאים באותו פרויקט Firebase. |
אינו זמין | שירות הודעות ענן אינו זמין באופן זמני. |
לא רשום | מופע האפליקציה לא נרשם מ-FCM. בדרך כלל זה אומר שאסימון הרישום של המכשיר שבו נעשה שימוש אינו תקף יותר ויש להשתמש באחד חדש. |
ניסיונות חוזרים אוטומטיים
ה-Admin SDK מנסה אוטומטית שגיאות מסוימות לפני חשיפת השגיאות הללו למשתמשים. באופן כללי, סוגי השגיאות הבאים מנוסים שוב בשקיפות:
- כל שגיאות ה-API הנובעות מתגובות HTTP 503 (שירות לא זמין).
- כמה שגיאות API הנובעות מתגובות HTTP 500 (שגיאת שרת פנימית).
- רוב שגיאות ה-I/O ברמה נמוכה (החיבור נדחה, איפוס החיבור וכו').
ה-SDK ינסה שוב כל אחת מהשגיאות הנ"ל עד 5 פעמים (הניסיון המקורי + 4 ניסיונות חוזרים) עם השבתה מעריכית. אתה יכול ליישם מנגנוני ניסיון חוזר משלך ברמת היישום אם תרצה, אבל זה בדרך כלל לא נדרש.
נסה שוב-לאחר תמיכה
ההטמעות Go ו-.NET של ה-Admin SDK מגיעות עם תמיכה בטיפול בכותרת HTTP Retry-After
. כלומר, אם תגובת השגיאה שנשלחה על ידי שרתי הקצה מכילה את הכותרת Retry-After
הסטנדרטית, ה-SDK יכבד זאת בעת ניסיון חוזר כל עוד משך ההמתנה שצוין אינו ארוך במיוחד. אם הכותרת Retry-After
מציינת משך המתנה ארוך מאוד, ה-SDK יעקוף נסיונות חוזרים ויזרוק את שגיאת ה-API המתאימה.
Python Admin SDK אינו תומך כרגע בכותרת Retry-After
, ותומך רק ב-backoff אקספוננציאלי פשוט.
דוגמאות לטיפול בשגיאות API
הטמעת מטפל שגיאות גנרי
ברוב המקרים מה שאתה רוצה הוא מטפל שגיאות גנרי שתופס מגוון רחב של שגיאות כדי למנוע סיום בלתי צפוי של זרימת התוכנית עקב שגיאת API. מטפלי שגיאות כאלה בדרך כלל פשוט רושמים את השגיאות למטרות ביקורת, או מפעילים שגרת ברירת מחדל אחרת לטיפול בשגיאות עבור כל שגיאות ה-API שנתקלו. הם לא בהכרח מתעניינים בקודי השגיאה השונים או בסיבות שאולי גרמו לשגיאה.
Java
try {
FirebaseToken token = FirebaseAuth.getInstance().verifyIdToken(idToken);
performPrivilegedOperation(token.getUid());
} catch (FirebaseAuthException ex) {
System.err.println("Failed to verify ID token: " + ex.getMessage());
}
פִּיתוֹן
try:
token = auth.verify_id_token(idToken)
perform_privileged_pperation(token.uid)
except exceptions.FirebaseError as ex:
print(f'Failed to verify ID token: {ex}')
ללכת
token, err := client.VerifyIDToken(ctx, idToken)
if err != nil {
log.Printf("Failed to verify ID token: %v", err)
return
}
performPrivilegedOperation(token)
.נֶטוֹ
try
{
var token = await FirebaseAuth.DefaultInstance.VerifyIdTokenAsync(idToken);
PerformPrivilegedOperation(token.getUid());
}
catch (FirebaseAuthException ex)
{
Conole.WriteLine($"Failed to verify ID token: {ex.Message}");
}
בדיקת קודי שגיאה
במקרים מסוימים, תרצה לבדוק את קודי השגיאה המדויקים, ולהפעיל שגרות שונות לטיפול בשגיאות מודעות להקשר. בדוגמה הבאה, יש לנו מטפל בשגיאות שמתעד הודעות שגיאה ספציפיות יותר על סמך קוד השגיאה של השירות.
Java
try {
FirebaseToken token = FirebaseAuth.getInstance().verifyIdToken(idToken);
performPrivilegedOperation(token.getUid());
} catch (FirebaseAuthException ex) {
if (ex.getAuthErrorCode() == AuthErrorCode.ID_TOKEN_EXPIRED) {
System.err.println("ID token has expired");
} else if (ex.getAuthErrorCode() == AuthErrorCode.ID_TOKEN_INVALID) {
System.err.println("ID token is malformed or invalid");
} else {
System.err.println("Failed to verify ID token: " + ex.getMessage());
}
}
פִּיתוֹן
try:
token = auth.verify_id_token(idToken)
perform_privileged_operation(token.uid)
except auth.ExpiredIdTokenError:
print('ID token has expired')
except auth.InvalidIdTokenError:
print('ID token is malformed or invalid')
except exceptions.FirebaseError as ex:
print(f'Failed to verify ID token: {ex}')
ללכת
token, err := client.VerifyIDToken(ctx, idToken)
if auth.IsIDTokenExpired(err) {
log.Print("ID token has expired")
return
}
if auth.IsIDTokenInvalid(err) {
log.Print("ID token is malformed or invalid")
return
}
if err != nil {
log.Printf("Failed to verify ID token: %v", err)
return
}
performPrivilegedOperation(token)
.נֶטוֹ
try
{
var token = await FirebaseAuth.DefaultInstance.VerifyIdTokenAsync(idToken);
PerformPrivilegedOperation(token.getUid());
}
catch (FirebaseAuthException ex)
{
if (ex.AuthErrorCode == AuthErrorCode.ExpiredIdToken)
{
Console.WriteLine("ID token has expired");
}
else if (ex.AuthErrorCode == AuthErrorCode.InvalidIdToken)
{
Console.WriteLine("ID token is malformed or invalid");
}
else
{
Conole.WriteLine($"Failed to verify ID token: {ex.Message}");
}
}
הנה דוגמה נוספת שבה אנו בודקים את קודי השגיאה ברמה העליונה וגם את קודי השירות:
Java
try {
FirebaseMessaging.getInstance().send(createMyMessage());
} catch (FirebaseMessagingException ex){
if (ex.getMessagingErrorCode() == MessagingErrorCode.UNREGISTERED) {
System.err.println("App instance has been unregistered");
removeTokenFromDatabase();
} else if (ex.getErrorCode() == ErrorCode.Unavailable) {
System.err.println("FCM service is temporarily unavailable");
scheduleForRetryInAnHour();
} else {
System.err.println("Failed to send notification: " + ex.getMessage());
}
}
פִּיתוֹן
try:
messaging.send(create_my_message())
except messaging.UnregisteredError:
print('App instance has been unregistered')
remove_token_from_database()
except exceptions.UnavailableError:
print('FCM service is temporarily unavailable')
schedule_for_retry_in_an_hour()
except exceptions.FirebaseError as ex:
print(f'Failed to send notification: {ex}')
ללכת
_, err := client.Send(ctx, createMyMessage())
if messaging.IsUnregistered(err) {
log.Print("App instance has been unregistered")
removeTokenFromDatabase()
return
}
if errorutils.IsUnavailable(err) {
log.Print("FCM service is temporarily unavailable")
scheduleForRetryInAnHour()
return
}
if err != nil {
log.Printf("Failed to send notification: %v", err)
return
}
.נֶטוֹ
try
{
await FirebaseMessaging.DefaultInstance.SendAsync(createMyMessage());
}
catch (FirebaseMessagingException ex)
{
if (ex.MessagingErrorCode == MessagingErrorCode.UNREGISTERED)
{
Console.WriteLine("App instance has been unregistered");
removeTokenFromDatabase();
}
else if (ex.ErrorCode == ErrorCode.Unavailable)
{
Console.WriteLine("FCM service is temporarily unavailable");
scheduleForRetryInAnHour();
}
else
{
Console.WriteLine($"Failed to send notification: {ex.Message}");
}
}
גישה לתגובת HTTP
במקרים נדירים מסוימים, ייתכן שתרצה לבדוק את תגובת שגיאת ה-HTTP המוחזרת על ידי שירות אחורי ולבצע עליה פעולה כלשהי לטיפול בשגיאות. ה-Admin SDK חושף הן את הכותרות והן את התוכן של תגובות השגיאה הללו. תוכן התגובה מוחזר בדרך כלל כמחרוזת או כרצף בתים גולמי, וניתן לנתח אותו לכל פורמט יעד הכרחי.
Java
try {
FirebaseMessaging.getInstance().send(createMyMessage());
} catch (FirebaseMessagingException ex){
IncomingHttpResponse response = ex.getHttpResponse();
if (response != null) {
System.err.println("FCM service responded with HTTP " + response.getStatusCode());
Map<String, Object> headers = response.getHeaders();
for (Map.Entry<String, Object> entry : headers.entrySet()) {
System.err.println(">>> " + entry.getKey() + ": " + entry.getValue());
}
System.err.println(">>>");
System.err.println(">>> " + response.getContent());
}
}
פִּיתוֹן
try:
messaging.send(create_my_message())
except exceptions.FirebaseError as ex:
response = ex.http_response
if response is not None:
print(f'FCM service responded with HTTP {response.status_code}')
for key, value in response.headers.items():
print(f'>>> {key}: {value}')
print('>>>')
print(f'>>> {response.content}')
ללכת
_, err := client.Send(ctx, createMyMessage())
if resp := errorutils.HTTPResponse(err); resp != nil {
log.Printf("FCM service responded with HTTP %d", resp.StatusCode)
for key, value := range resp.Header {
log.Printf(">>> %s: %v", key, value)
}
defer resp.Body.Close()
b, _ := ioutil.ReadAll(resp.Body)
log.Print(">>>")
log.Printf(">>> %s", string(b))
return
}
.נֶטוֹ
try
{
await FirebaseMessaging.DefaultInstance.SendAsync(createMyMessage());
}
catch (FirebaseMessagingException ex)
{
var response = ex.HttpResponse
if response != null
{
Console.WriteLine($"FCM service responded with HTTP { response.StatusCode}");
var headers = response.Headers;
for (var entry in response.Headers)
{
Console.WriteLine($">>> {entry.Key}: {entry.Value}");
}
var body = await response.Content.ReadAsString();
Console.WriteLine(">>>");
Console.WriteLine($">>> {body}");
}
}