Обновление 2021 года: я больше не рекомендую этот метод. Хотя технически он все еще работает, при использовании его в недавнем проекте мы столкнулись с множеством устаревших проблем с входом в систему.

Вместо этого вам следует пойти другим путем и использовать логин gapi для передачи учетных данных в Firebase.

Я рекомендую следовать инструкциям здесь: https://github.com/msukmanowsky/gapi-firebase

Я также рекомендую использовать этот вспомогательный модуль для загрузки gapi: https://www.npmjs.com/package/gapi-script

Исходное сообщение:

Если вы создаете веб-приложение, которое должно взаимодействовать с учетной записью Google пользователя, есть вероятность, что вы обнаружите, что OAuth неудобно. Вам нужно получить токен OAuth и передать его в библиотеку Google API, прежде чем вы сможете сделать что-нибудь полезное.

К счастью, выполнять все операции входа в систему с помощью Firebase Auth очень просто, а Firebase UI делает это еще проще.

Пользовательский интерфейс Firebase - это, по сути, отдельная библиотека, которая автоматически выполняет весь пользовательский интерфейс (кнопки и т. Д.) И логику перенаправления для всех поддерживаемых провайдеров Firebase OAuth (Google, Facebook, GitHub и т. Д.).

Проблема в том, что когда вы хотите сделать больше, чем просто войти в систему, все становится неясным. Допустим, вы хотели создать приложение, которое управляет календарем пользователя. Как указать объемы, необходимые для доступа к другим службам Google? Как получить токен OAuth из пользовательского интерфейса Firebase для использования в клиенте API Google?

К счастью, Тодд Вандерлин написал отличный пост, в котором исправлены многие из этих проблем. Взяв это за основу, давайте посмотрим, как вы можете заставить Firebase UI и Google API Client работать вместе!

Настроить библиотеки

Первым шагом является установка Firebase и Firebase UI. Вы можете просто следовать официальным инструкциям или следовать здесь.

Добавьте следующее в раздел ‹head› в HTML:

<script src="https://www.gstatic.com/firebasejs/4.8.1/firebase.js"></script>
<script src="https://cdn.firebase.com/libs/firebaseui/2.5.1/firebaseui.js"></script>
<link rel="stylesheet" href="https://cdn.firebase.com/libs/firebaseui/2.5.1/firebaseui.css" />

Это загрузит все зависимости из CDN Google.

Настройка конфигурации

Во-первых, убедитесь, что вы включили Google Login в консоли Firebase:

Перейдите в консоль Firebase и получите данные конфигурации для своего приложения.

Это должно выглядеть примерно так:

var config = {
    apiKey: "RANDOM_STRING",
    authDomain: "APPNAME.firebaseapp.com",
    databaseURL: "https://APPNAME.firebaseio.com",
    projectId: "APPNAME",
    storageBucket: "APPNAME.appspot.com",
    messagingSenderId: "1234567890"
  };

Мы собираемся использовать этот объект конфигурации для настройки API Google, а также Firebase. Для этого вам нужно добавить в этот объект еще несколько полей.

ID клиента

Первое, что вам нужно сделать, это получить свой идентификатор клиента OAuth. Для этого вам нужно зайти в консоль разработчика Google.

Console.developers.google.com/apis/credentials

Теперь добавьте это в свой объект конфигурации

var config = {
    apiKey: "RANDOM_STRING",
    authDomain: "APPNAME.firebaseapp.com",
    databaseURL: "https://APPNAME.firebaseio.com",
    projectId: "APPNAME",
    storageBucket: "APPNAME.appspot.com",
    messagingSenderId: "1234567890",
    clientId: "RANDOM_STRING.apps.googleusercontent.com"
  };

Области применения

Затем вам нужно добавить области, которые вам нужны для услуг, которые вы хотите изменить. В этом примере я хочу получить информацию профиля пользователя (адрес электронной почты, имя и т. Д.) И иметь возможность изменять и читать его календарь.

Чтобы найти правильное имя области, здесь есть список всех доступных областей действия Google:

Https://developers.google.com/identity/protocols/googlescopes

Теперь найдите нужные вам прицелы. Некоторые службы (например, Gmail) имеют очень специфические возможности, которые предоставляют вам минимальный доступ, необходимый для выполнения задачи. Всегда убедитесь, что вы используете наименьшее количество необходимых разрешений!

Итак, в этом примере есть три области, которые нужно включить: «электронная почта», «профиль» и «https://www.googleapis.com/auth/calendar».

Создайте массив в объекте конфигурации со следующими значениями:

var config = {
    apiKey: "RANDOM_STRING",
    authDomain: "APPNAME.firebaseapp.com",
    databaseURL: "https://APPNAME.firebaseio.com",
    projectId: "APPNAME",
    storageBucket: "APPNAME.appspot.com",
    messagingSenderId: "1234567890",
    clientId: "RANDOM_STRING.apps.googleusercontent.com",
    scopes: [
             "email",
             "profile",
             "https://www.googleapis.com/auth/calendar"
    ]
};

Документы Discovery

Время для последнего шага. Чтобы клиент Google API знал, какие библиотеки загружать, вам необходимо передать соответствующие документы обнаружения. Электронная почта и профиль встроены в Firebase, но мы хотим иметь возможность изменять календарь с помощью клиента Google API, поэтому нам нужен документ обнаружения для этого.

Чтобы найти нужный документ об обнаружении, вы можете использовать эту службу:

Https://developers.google.com/discovery/v1/reference/apis/list?apix=true

Опять же, создайте массив и добавьте все необходимые документы по обнаружению.

var config = {
    apiKey: "RANDOM_STRING",
    authDomain: "APPNAME.firebaseapp.com",
    databaseURL: "https://APPNAME.firebaseio.com",
    projectId: "APPNAME",
    storageBucket: "APPNAME.appspot.com",
    messagingSenderId: "1234567890",
    clientId: "RANDOM_STRING.apps.googleusercontent.com",
    scopes: [
             "email",
             "profile",
             "https://www.googleapis.com/auth/calendar"
    ],
    discoveryDocs: [
    "https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest"
    ]
};

Наконец-то покончено со всем конфигом безумия!

Настройка пользовательского интерфейса Firebase

Примечание: Здесь вы можете увидеть заполненный код

Следуйте официальной настройке Firebase UI. Единственное отличие заключается в поле «signInOptions». Измените его, чтобы включить области, указанные в объекте конфигурации:

var uiConfig = {
 signInSuccessUrl: “<url-to-redirect-to-on-success>”,
 signInOptions: [{
   provider: firebase.auth.GoogleAuthProvider.PROVIDER_ID,
   scopes: config.scopes
 }],
 // Terms of service url.
 tosUrl: “<your-tos-url>”
};

Настройка клиента Google API

Пользовательский интерфейс Firebase позаботится обо всех деталях процесса входа в систему. После завершения входа Firebase автоматически запустит функцию. Внутри этой функции мы загрузим клиент Google API.

// This function will trigger when there is a login event
firebase.auth().onAuthStateChanged(function(user) {
  // Make sure there is a valid user object
  if(user){
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = 'https://apis.google.com/js/api.js';
    // Once the Google API Client is loaded, you can run your code
    script.onload = function(e){
     // Initialize the Google API Client with the config object
     gapi.client.init({
       apiKey: config.apiKey,
       clientId: config.clientID,
       discoveryDocs: config.discoveryDocs,
       scope: config.scopes.join(' '),
     })
     // Loading is finished, so start the app
     .then(function() {
      // Make sure the Google API Client is properly signed in
      if (gapi.auth2.getAuthInstance().isSignedIn.get()) {
        startApp(user);
      } else {
        firebase.auth().signOut(); // Something went wrong, sign out
      }
     })
    }
    // Add to the document
    document.getElementsByTagName('head')[0].appendChild(script);  
  }
})

Связывая все вместе

Все "шаблонное" готово. Теперь вы можете без проблем использовать Google API Client!

Примечание. Важно, чтобы вы либо проверили, действителен ли токен OAuth перед вызовом, либо обновили токен перед вызовом API. Это связано с тем, что Firebase автоматически обновит токен, а клиент Google API - нет.

// Print out the User and the 10 latest calendar events
function startApp(user) {
  console.log(user);
  firebase.auth().currentUser.getToken()
  .then(function(token) {
    return gapi.client.calendar.events.list({
     calendarId: "primary",
     timeMin: new Date().toISOString(),
     showDeleted: false,
     singleEvents: true,
     maxResults: 10,
     orderBy: "startTime"
    })  
   })
  .then(function(response) {
    console.log(response);  
  });
}

Полный код: