带有React的Google Calendar API

时间:2018-03-19 17:19:46

标签: reactjs firebase google-calendar-api gapi

我正在尝试在React和Firebase应用中使用Google Calendar API。我正在App.js组件中向Google进行身份验证,同时我尝试在Calendar.js组件中访问Google Calendar API。

这是我的App.js

import React from 'react'
import firebase from 'firebase'
import './App.css'
import AppBody from '../AppBody'
import AppHeader from '../AppHeader'


class App extends React.Component {

  constructor() {
    super()
    this.state = {
      user: null,
      googleAuth: null
    }
  }

  componentDidMount() {

    // capture authentication callback
    firebase.auth().onAuthStateChanged(user => {
      if (user !== this.state.user) {
        this.setState({user})
      }
    })

    const script = document.createElement('script')
    script.src = 'https://apis.google.com/js/api.js'

    script.onload = () => {
      window.gapi.load('client:auth2', () => {
        window.gapi.client.init({
          clientId: 'client_Id',
          scope: 'https://www.googleapis.com/auth/calendar'
        }).then(() =>
          this.setState({googleAuth: window.gapi.auth2.getAuthInstance()})
        )
      })
    }

    document.head.appendChild(script)
  }

  handleAuthClick = () => {

    let {googleAuth} = this.state

    if (this.state.user) {

      googleAuth.signOut().then(firebase.auth().signOut())

    } else {

      googleAuth.signIn().then(googleUser => {

          var unsubscribe = firebase.auth().onAuthStateChanged(firebaseUser => {
            unsubscribe()

            if (!isUserEqual(googleUser, firebaseUser)) {

              var credential = firebase.auth.GoogleAuthProvider.credential(googleUser.getAuthResponse().id_token)
              firebase.auth().signInWithCredential(credential)
                .then(user => this.setState({user}))
                .catch(error => console.error(error))

            } else {

              console.log('User already signed-in Firebase.')
              console.log(googleUser)
            }
          })
      })

      let isUserEqual = (googleUser, firebaseUser) => {
        if (firebaseUser) {
          var providerData = firebaseUser.providerData
          for (let i = 0; i < providerData.length; i++) {
            if (providerData[i].providerId === firebase.auth.GoogleAuthProvider.PROVIDER_ID &&
                providerData[i].uid === googleUser.getBasicProfile().getId()) {
              return true
            }
          }
        }
        return false
      }
    }
  }

  render() {

    let {user} = this.state

    return (
      <div>
        <AppHeader onAuthClick={this.handleAuthClick} user={user} />
        {user ? <AppBody userID={user.uid} /> : undefined}
      </div>
    )
  }
}

export default App

这是我的Calendar.js(由AppBody组件加载)

import React from 'react'
import './Calendar.css'


class Calendar extends React.Component {

  constructor(props) {
    super(props)
    this.state = {
      events: []
    }
  }

  componentDidMount() {

    if (window.gapi && window.gapi.client) {

      var timeMin = new Date()
      timeMin.setHours(0, 0, 0)

      var timeMax = new Date()
      timeMax.setHours(23, 59, 59)

      window.gapi.client.load('calendar', 'v3', () => {
        window.gapi.client.calendar.events.list({
          'calendarId': 'primary',
          'timeMin': timeMin.toISOString(),
          'timeMax': timeMax.toISOString(),
          'singleEvents': true
        }).then(response => {
          let events = []
          response.result.items.forEach(event => {
            events.push({
              title: event.summary,
              start: new Date(event.start.dateTime),
              end: new Date(event.end.dateTime)
            })
          })
          this.setState({events})
        })
      })
    }
  }

  render() {

    console.log(this.state.events)

    return (
      ...render events...
    )
  }
}

export default Calendar

问题是,如果我不断刷新屏幕,我会得到非常不一致的结果:

  • 有时我会得到并呈现事件列表。
  • 通常情况下,我没有发生任何事件。
  • 有时,我收到以下错误:

Uncaught {result: {…}, body: "{↵ "error": {↵ "errors": [↵ {↵ "domain": "us…e Exceeded. Continued use requires signup."↵ }↵}↵", headers: {…}, status: 403, statusText: null}

我显然没有正确使用Calendar API。我做错了什么?

1 个答案:

答案 0 :(得分:0)

假设window.gapi是您通过脚本标记设置并调用窗口对象的Calendar API对象,请考虑在您在componentDidMount中调用脚本时是否已加载脚本。

如果脚本在组件安装之前进行竞争,则会生成事件。 如果在安装组件时未加载脚本,则state.events数组将为空,从而不会发生任何事件。 最后一个错误似乎是配额错误;您可以在此处查看您的API设置:https://console.cloud.google.com/apis/api/calendar-json.googleapis.com/overview