使用Firebase构建云端应用:建立项目和用户管理

在构建本身的在线云工具应用时,我使用 Firebase 为本身的“无后端项目”提供服务,把在开发期间接触到的一些内容整理在一块儿,制成系列笔记。这个过程有两个好处:巩固知识点,整理开发过程的思路。由于前端开发是本身所熟悉的领域,因此先从 Firebase 入手,将后端的一些知识点提早梳理理顺,避免后续的学习过程当中的卡壳而致使没法坚持。今天第一期:建立项目和用户管理。前端

什么是 Firebase

Firebase 本来是一家实时后端数据库创业公司,为提供一个实时响应的数据服务。后被 Google 收购,该平台适用在IOS、Android、web前端等各类跨平台上,对于没有数据库处理经验的开发者,只需使用本身熟悉的语言将数据放在Firebase上,再经过Firebase提供的API便可实现实时数据同步。同时 Google 在新版的 Firebase 中包含开发、成长与营收三阶段,并整合分析工具,不过度析工具目前只针对移动 App,网页的话能够继续使用 Google Analytics。git

何谓“实时数据库”?简单粗暴的理解就是,数据库中数据的变更会互动通知到客户端。同一帐号在客户端 A出操做,客户端 B 会收到相应的通知。根据我在浏览器中的调试,发如今 Web 端 原来是用的 WebSocket。考虑到写数据时遇到的无网络链接问题,Firebase的数据库API使用了本地缓存,使得在离线状态下也能保持读写不失败,而且会在网络恢复链接时和服务器进行同步。github

Firebase 提供了四种 SDK: Android,IOS, Web 和 C++。我将使用 Web 端 SDK 开发一个无后端的笔记应用。web

关联应用

在使用 Firebase 做为后端数据库以前,须要登陆 Firebase 的控制台,添加一个 Firebase 的网络应用。你可选择新建一个应用,或者导入一个现有的 Google 项目。数据库

建立完应用以后,进入应用的控制面板,在 ‘https://console.firebase.goog...’ 中能够看到硕大的绑定入口“将 Firebase 添加到您的网页应用”,点击以后,将给处的 JavaScript 添加到 HTML 文件中。npm

<script src="https://www.gstatic.com/firebasejs/3.4.0/firebase.js"></script>
  <script>
    // Initialize Firebase
    let config = {
      apiKey: '<your-api-key>',
      authDomain: '<your-auth-domain>',
      databaseURL: '<your-database-url>',
      storageBucket: '<your-storage-bucket>'
    };
    firebase.initializeApp(config);
  </script>

固然也可经过 npm 安装 Firebase 的 SDK npm link,而后经过 Webpack 等工具打包。后端

npm install --save firebase

引入 Firebaseapi

let firebase = require('firebase');
let app = firebase.initializeApp({ ... });

完整的 Firebase 客户端包包含了Firebase 的 Authentication, Realtime Database, Storage 和 Cloud Messaging。上面的代码将会把这些功能所有引入。能够将这些功能以独立组件的形式引入,减小代码量。浏览器

  • firebase-app 核心代码(必需)缓存

  • firebase-auth Authentication(可选)

  • firebase-database Realtime Database(可选)

  • firebase-storage Storage(可选)

  • firebase-messaging Cloud Messagin(可选)

在这个案例中目前 Storage暂时没有使用的计划,Cloud Messaging 针对的是移动端,因此这两个组件不引入。

let firebase = require('firebase/app');
require('firebase/auth');
require('firebase/database');
 
let app = firebase.initializeApp({ ... });
// ...

完成上述步骤以后,你已经能够在环境中使用 firebase 提供的各类接口了。

用户

大多数应用都须要了解用户的身份。知道用户的身份可让应用将用户数据安全地保存在云中并跨全部用户设备提供相同的个性化体验。
Firebase Authentication 提供后端服务、易用 SDK 和现成 UI 库来向应用验证用户的身份。它支持使用密码、深受欢迎的联合用户身份提供商(如 Google、Facebook 和 Twitter)等方法进行身份验证。

本次案例使用第三方登陆,不使用 Firebase 提供的 UI库,有兴趣的朋友能够本身去试试 https://github.com/firebase/FirebaseUI-Web

在添加了 Firebase应用以后,打开console的 Authentication,在登陆方法中开启须要的登陆提供商。这里我选择了“电子邮件地址/密码”和“Github“两种方式。

建立基于密码的账户

在用户填写表单注册时,完成所需的任何新账户验证步骤,例如验证新账号密码键入正确,或者检查帐号是否已经存在。而后
将邮件地址和密码传递到 createUserWithEmailAndPassword 方法中来建立新账户:

firebase.auth().signInWithEmailAndPassword(email, password).catch((error) => {
  // Handle Errors here.
  let errorCode = error.code;
  let errorMessage = error.message;
  // ...
});

用户首次登陆后,便会创建一个新用户账户并连接至该用户登陆时使用的凭据,即用户名和密码,或身份验证提供程序信息。此新账户存储在 Firebase 项目中,可用于跨项目中的每一个应用识别用户,不管该用户如何登陆。

使用 Github 帐号登陆

在console 中的登陆方式中启用 github 登陆以后,须要添加从 GitHub 得到的 OAuth 2.0 客户端 ID 和客户端密钥。同时将你的 Github 应用的受权回调地址设置为 Firebase OAuth 重定向 URI(例如 my-app-12345.firebaseapp.com/__/auth/handler)。Github 的应用配置

上述前期工做准备就绪以后,能够开始使用 Firebase SDK 来使用登陆流程。

先建立一个 GitHub 提供程序对象的实例:

let provider = new firebase.auth.GithubAuthProvider();

而后是一个可选的步骤:从身份验证提供程序中指定您想请求的其余 OAuth 2.0 范围。调用 Provider 实例的 addScope方法来添加范围。例如:

provider.addScope('repo');

详细参数能够参考身份验证提供程序文档

接下来,使用 GitHub 提供程序对象进行 Firebase 身份验证。能够提示用户,让其经过打开弹出式窗口或重定向登陆页面的方法以本身的 GitHub account 登陆。移动设备最好使用重定向方法。要用弹出式窗口的方法登陆,调用 signInWithPopup:

firebase.auth().signInWithPopup(provider).then(function(result) {
  // This gives you a GitHub Access Token. You can use it to access the GitHub API.
  let token = result.credential.accessToken;
  // The signed-in user info.
  let user = result.user;
  // ...
}).catch(function(error) {
  // Handle Errors here.
  let errorCode = error.code;
  let errorMessage = error.message;
  // The email of the user's account used.
  let email = error.email;
  // The firebase.auth.AuthCredential type that was used.
  let credential = error.credential;
  // ...
});

你能够检索 GitHub 提供程序的 OAuth 令牌,使用该令牌可经过 GitHub API 提取额外数据。
还能够经过这种方法捕获并处理错误。获取错误代码列表

若是要用重定向登陆页面的方法登陆,则调用 signInWithRedirect:

firebase.auth().signInWithRedirect(provider);

不只如此,你还能够在页面加载时经过调用 getRedirectResult 检索 GitHub 提供程序的 OAuth 令牌:

firebase.auth().getRedirectResult().then(function(result) {
  if (result.credential) {
    // This gives you a GitHub Access Token. You can use it to access the GitHub API.
    let token = result.credential.accessToken;
    // ...
  }
  // The signed-in user info.
  let user = result.user;
}).catch(function(error) {
  // Handle Errors here.
  let errorCode = error.code;
  let errorMessage = error.message;
  // The email of the user's account used.
  let email = error.email;
  // The firebase.auth.AuthCredential type that was used.
  let credential = error.credential;
  // ...
});

固然,你也能够手动处理登陆流程。 在 GitHub 登陆流程结束后,你会收到一个 OAuth 2.0 访问令牌。在用户使用 GitHub 成功登陆以后,先使用 OAuth 2.0 访问令牌换取 Firebase 凭据:

let credential = firebase.auth.GithubAuthProvider.credential(token);

而后使用 Firebase 凭据进行 Firebase 身份验证:

firebase.auth().signInWithCredential(credential).catch(function(error) {
  // Handle Errors here.
  let errorCode = error.code;
  let errorMessage = error.message;
  // The email of the user's account used.
  let email = error.email;
  // The firebase.auth.AuthCredential type that was used.
  let credential = error.credential;
  // ...
});

除了前面提到的邮箱密码验证,第三方 OAuth 验证以外,Firebase 还支持自定义身份认证系统和匿名身份验证,这里不讲,有兴趣和需求的朋友能够本身去了解。

其余用户管理操做的支持

要注销用户,调用 signOut:

firebase.auth().signOut().then(() => {
  // Sign-out successful.
}, function(error) {
  // An error happened.
});

除此以外,SDK 还提供了一系列用户管理的方法。

  • 获取当前登陆的用户

获取当前用户的推荐方法是在 Auth 对象上调用onAuthStateChanged方法,这可确保在您获取当前用户时,Auth 对象不会处于中间状态,例如初始化。既要么未登陆,要么已登陆。

firebase.auth().onAuthStateChanged((user) => {
  if (user) {
    // User is signed in.
  } else {
    // No user is signed in.
  }
});

也可使用 currentUser 属性获取当前已登陆的用户。 若是用户没有登陆,currentUser 则为 null:

let user = firebase.auth().currentUser;

if (user) {
  // User is signed in.
} else {
  // No user is signed in.
}

不过有一点要注意,currentUser 还可能因为 auth 对象还没有完成初始化而为 null。 若是使用观察程序跟踪用户登陆状态,则无需处理该状况。
当获取到用户对象的实例以后,能够访问实例上的一些属性,以及调用实例上的一些方法对用户进行一些操做,好比:

  • 要获取用户的我的资料信息:

let user = firebase.auth().currentUser;
let name, email, photoUrl, uid;

if (user != null) {
  name = user.displayName;
  email = user.email;
  photoUrl = user.photoURL;
  uid = user.uid;  // The user's ID, unique to the Firebase project. Do NOT use
                   // this value to authenticate with your backend server, if
                   // you have one. Use User.getToken() instead.
}
  • 获取用户的特定于提供程序的我的资料信息(登陆提供程序中获取检索到的我的资料信息)

let user = firebase.auth().currentUser;

if (user != null) {
  user.providerData.forEach(function (profile) {
    console.log("Sign-in provider: "+profile.providerId);
    console.log("  Provider-specific UID: "+profile.uid);
    console.log("  Name: "+profile.displayName);
    console.log("  Email: "+profile.email);
    console.log("  Photo URL: "+profile.photoURL);
  });
}
  • 更新用户我的资料(显示名称和头像地址)

let user = firebase.auth().currentUser;

user.updateProfile({
  displayName: "Jane Q. User",
  photoURL: "https://example.com/jane-q-user/profile.jpg"
}).then(function() {
  // Update successful.
}, function(error) {
  // An error happened.
});
  • 设置电子邮件地址

let user = firebase.auth().currentUser;

user.updateEmail("user@example.com").then(function() {
  // Update successful.
}, function(error) {
  // An error happened.
});

要设置用户的电子邮件地址,该用户必须最近登陆过。在 Firebase 控制台的"Authentication"的"Email Templates"页面中容许自定义使用的电子邮件模板。

  • 设置用户密码

let user = firebase.auth().currentUser;
let newPassword = getASecureRandomPassword();

user.updatePassword(newPassword).then(function() {
  // Update successful.
}, function(error) {
  // An error happened.
});
  • 删除用户

也能够在控制台中手动删除用户

let user = firebase.auth().currentUser;

user.delete().then(function() {
  // User deleted.
}, function(error) {
  // An error happened.
});

有些安全敏感性操做,好比删除账户、设置主电子邮件地址和更改密码,须要用户最近登陆过才能执行。若是要执行这些操做中的某一项,而用户只是在好久之前登陆过,操做便出错。发生这种错误时,须要从用户获取新登陆凭据,将该凭据传给 reauthenticate ,对该用户从新进行身份验证。

let user = firebase.auth().currentUser;
let credential;

// Prompt the user to re-provide their sign-in credentials

user.reauthenticate(credential).then(function() {
  // User re-authenticated.
}, function(error) {
  // An error happened.
});

结束

如此一来,个人应用已经能够支持邮箱密码登陆,github 帐号登陆。并且用户的管理操做也有很直接明了的方法。当用户添加以后,接下来就能够围绕用户设计出须要的数据结构了。下回:数据结构的定义及数据的操做,敬请期待

相关文章
相关标签/搜索