Social Preview

简化 iOS 和 macOS 上的 Firebase 开发。

🍏 只需一行代码即可完成第三方身份验证

✉️ 轻松发送和接收 Firestore 文档

😀 具有内置功能的预定义用户协议

🔥 一个原生 Swift 包中的 Firebase 解决方案

📘 代码完全文档化,并附带示例


⚠️ 注意: 此软件包仍在开发中,其内容可能会随时更改。

📚 准备好开始了吗? 查看我们的完整 wiki 以获取详细指南。

GitHub release (latest SemVer) GitHub Release Date GitHub issues GitHub pull requests

什么是 EasyFirebase?

EasyFirebase 是一个用于所有 Firebase 功能的 Swift 封装器。 避免在项目中重复实现 Firebase 代码,节省您大量时间。 EasyFirebase 通过为 Firestore 提供直观的协议,简化了文档的存储和检索。 通过 EasyUser (可子类化) 开放类和使用 Google 和 Apple 的简单一键登录,EasyFirebase 简化了身份验证。 EasyFirebase 是跨平台的,可与 iOS 和 macOS 一起使用。

已完成的功能

以上所有功能都是跨平台的,并且在 iOS 和 macOS 上均受支持。

⭐️ 这意味着 EasyFirebase 是在 macOS 上实现使用 Google 登录的最快方法!⭐️

开始使用

使用 Swift Package Manager 将 EasyFirebase 添加到您的项目中

https://github.com/Flowductive/easy-firebase

导入 EasyFirebase

import EasyFirebase

在应用启动时进行配置

// You don't need to call FirebaseApp.configure() when this is called!
EasyFirebase.configure()

🔥 Firestore 功能展示

内置 Document 协议

使用内置的 Document 协议节省编写模型类的时间

class Car: Document {
  
  // These properties are inherited from Document
  var id: String = UUID().uuidString
  var dateCreated: Date = Date()
  
  // Define your own custom properties
  var make: String
  var model: String
  var year: Int
  
  init(make: String, model: String, year: Int) {
    // ...
  }
}

文档存储

将文档存储在代码中的任何位置

var myCar = Car(make: "Toyota", model: "Corolla", year: 2017)

// Store the car instance in the 'car' collection in Firestore
myCar.set()

// Static method that does the same as above
EasyFirestore.Storage.set(myCar)

文档检索

轻松获取文档,而无需指定集合名称

EasyFirestore.Retrieval.get(id: myCarID, ofType: Car.self) { car in
  guard let car = car else { return }
  self.myOtherCar = car
}

文档更新

无需执行任何读取操作即可在 Firestore 中远程更新字段。

// Append element to array
EasyFirestore.Updating.append(\.ingredients, with: "Cheese", in: pizzaDocument) { error in ... }

// Increment field
EasyFirestore.Updating.increment(\.pepperoniCount, by: 5, in: pizzaDocument)

// Remove elements from array
EasyFirestore.Updating.remove(\.ingredients, taking: ["Garlic", "Anchovies", "Pineapple"], from: pizzaDocument)

更新监听器

在 Firestore 中更改文档时,获取文档并更新本地实例

EasyFirestore.Listening.listen(to: otherCarID, ofType: Car.self, key: "myCarListenerKey") { car in
  // Updates when changed in Firestore
  guard let car = car else { return }
  self.myOtherCar = car
}

内置缓存

EasyFirestore 会自动在本地缓存获取的文档,并在检索时使用缓存的文档,以减少您的 Firestore 读取次数。

// EasyFirebase will automatically cache fetched objects for you, here is a manual example
EasyFirestore.Cacheing.register(myCar)

// Get locally cached objects instantly. Retrieving objects using EasyFirestore.Retrieval will grab cached objects if they exist
var cachedCar = EasyFirestore.Cacheing.grab(myCarID, fromType: Car.self)

轻松链接

将子文档链接到父文档中的 ID 数组

var car1 = Car(make: "Toyota", model: "Corolla", year: 2017)
var car2 = Car(make: "Honda", model: "Civic", year: 2019)

var dealership = Dealership(name: "Los Angeles Dealership")

// Set and assign the Toyota Corolla to the Los Angeles Dealership
car1.setAssign(toField: "cars", using: \.cars, in: dealership)

// Set and assign the Honda Civic to the Los Angeles Dealership
car2.set()
car2.assign(toField: "cars", using: \.cars, in: dealership)

Swifty 查询

轻松查询文档

EasyFirestore.Querying.where(\Car.make, .equals, "Toyota") { cars in
  // Handle your queried documents here...
}

使用多个条件进行查询;排序和限制结果

EasyFirestore.Querying.where((\Car.year, .greaterEqualTo, 2010),
                             (\Car.model, .in, ["Corolla", "Camry"]),
                             order: .ascending,
                             limit: 5
) { cars in
  // ...
}

🔑 身份验证功能展示

Easy User 协议

使用内置的 EasyUser 开放类节省编写用户类的时间

class MyUser: EasyUser {
  
  // EasyUser comes pre-built with these automatically updated properties
  var lastSignon: Date
  var displayName: String
  var username: String
  var email: String
  var appVersion: String
  var deviceToken: String?
  var notifications: [MessagingNotification]
  var disabledMessageCategories: [MessageCategory]
  var progress: Int
  var id: String
  var dateCreated: Date
  
  // Define your own custom properties
  var cars: [Car.ID]

  // ...
}

⚠️ 注意: 请务必阅读该 wiki 以正确实施此操作!

电子邮件验证

使用电子邮件和密码轻松进行身份验证

EasyAuth.createAccount(email: "easy.firebase@example.com", password: "76dp2[&y4;JLyu:F") { error in
  if let error = error {
    print(error.localizedDescription)
  } else {
    // Account created!
  }
}

EasyAuth.signIn(email: "easy.firebase@example.com", password: "76dp2[&y4;JLyu:F") { error in
  // ...
}

使用 Google 登录

使用 Google 进行身份验证

// iOS
EasyAuth.signInWithGoogle(clientID: "xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx") { error in
  // ...
}

// macOS
EasyAuth.signInWithGoogle(clientID: "xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                          secret: "GOCSPX-xxxxxxxxxxxxxxxxxxx-xxxxxxxx") { error in
  // ...
}

使用 Apple 登录

使用 Apple 进行身份验证

// iOS + macOS
EasyAuth.signInWithApple()

内置用户名

生成唯一的用户名并轻松更新

user.safelyUpdateUsername(to: "myNewUsername", ofUserType: MyUser.self) { error, suggestion in
 if let error = error {
   // ...
 } else if let suggestion = suggestion {
   // Username taken, provide the user with an available username suggestion.
 } else {
   // Success! Username changed.
 }
}

强大的用户管理

快速更新和管理 EasyAuth 用户

// Send a verfication email to the currently signed-in user
user.sendEmailVerification(completion: { error in })
// Upload and update the current user's profile photo
user.updatePhoto(with: myPhotoData, ofUserType: FUser.self, completion: { error in })
// Send the current user's password reset form to a specified email
user.sendPasswordReset(toEmail: "myResetEmail@example.com", completion: { error in })
// Update the current user's display name
user.updateDisplayName(to: "New_DisplayName", ofUserType: MyUser.self, completion: { error in })
// Update the current user's password
user.updatePassword(to: "newPassword", completion: { error in })
// Delete the current user
user.delete(ofUserType: MyUser.self, completion: { error in })

📦 存储功能展示

数据存储

使用单行代码快速将数据分配给 Firebase Storage。

// Upload image data and get an associated URL
EasyStorage.put(imageData, to: StorageResource(id: user.id)) { url in }

// EasyStorage will automatically delete existing images matching the same ID (if in the same folder)
EasyStorage.put(imageData,to: StorageResource(id: user.id, folder: "myFolder"), progress: { updatedProgress in
  // Update progress text label using updatedProgress
}, completion: { url in
  // Handle the image's URL
})

☁️ 云消息传递功能展示

内置用户通知

轻松发送和通知其他用户,而无需所有繁琐的设置。 只需从 Firebase 控制台 添加一个 serverKey

// Set your Server Key
EasyMessaging.serverKey = "xxxxxxxxxxx:xxxxxxxxxxxxxxxxxxxxx-xxxxx-xxxxxxxxxxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxx"

// Create the notification
let notification = MessagingNotification("Message body", from: me, in: "Test Category")

// Send the notification to the user
// Appends to the notifications property, unless the specified category is in the user's disabledMessageCategories
EasyMessaging.send(notification, to: you)

📊 分析功能展示

轻松记录事件

要记录事件,您可以使用 EasyAnalytics 的静态方法

EasyAnalytics.log("food_eaten", data: [
 "name": "Hot Dog",
 "isHot": true
])

如果您有一个符合 AnalyticsLoggable 的模型,您可以使用模型本身来记录事件

let hotdog = Food(name: "Hot Dog", temperature: 81)
EasyAnalytics.log("food_eaten", model: hotdog)

或者,您可以从模型本身调用记录方法

hotdog.log(key: "food_eaten")

集成的用户属性

覆盖 analyticsProperties() 方法,以便在应用程序启动时自动更新用户属性

struct MyUser: EasyUser {
  // ...
  var favoriteCar: String
  func analyticsProperties() -> [String: String] {
    return ["app_version": appVersion, "favorite_car": favoriteCar]
  }
}

手动将用户属性更新到 Firebase Analytics

myUser.updateAnalyticsUserProperties()