All Projects → 1amageek → Salada

1amageek / Salada

Licence: other
Firebase model framework Salada. Salada is the best Firebase framework.

Programming Languages

swift
15916 projects

Projects that are alternatives of or similar to Salada

Rxfirebase
Rxjava 2.0 wrapper on Google's Android Firebase library.
Stars: ✭ 509 (+123.25%)
Mutual labels:  database, firebase, firebase-database
Nora
Nora is a Firebase abstraction layer for FirebaseDatabase and FirebaseStorage
Stars: ✭ 270 (+18.42%)
Mutual labels:  database, firebase, firebase-database
Firebase Esp8266
ESP8266 Firebase RTDB Arduino Library
Stars: ✭ 228 (+0%)
Mutual labels:  database, firebase, firebase-database
Firebase Server
Firebase Realtime Database Server Implementation
Stars: ✭ 673 (+195.18%)
Mutual labels:  database, firebase, firebase-database
Quickstart Cpp
Firebase Quickstart Samples for C++
Stars: ✭ 123 (-46.05%)
Mutual labels:  firebase, firebase-database
Firebasecrud
Rich UI and animation flutter app backed by firebase
Stars: ✭ 121 (-46.93%)
Mutual labels:  firebase, firebase-database
Petshop
Pet Shop is an e-commerce application for Android built with Flutter (iOS to come soon).
Stars: ✭ 127 (-44.3%)
Mutual labels:  firebase, firebase-database
Space
A real time chat app for developers built using React, Redux, Electron and Firebase
Stars: ✭ 161 (-29.39%)
Mutual labels:  firebase, firebase-database
Gatsby Theme Firebase
🔥 A Gatsby Theme for adding Firebase to your application.
Stars: ✭ 96 (-57.89%)
Mutual labels:  firebase, firebase-database
Combinefirebase
Combine wrapper on Google's iOS Firebase library.
Stars: ✭ 126 (-44.74%)
Mutual labels:  database, firebase
Space Cloud
Open source Firebase + Heroku to develop, scale and secure serverless apps on Kubernetes
Stars: ✭ 3,323 (+1357.46%)
Mutual labels:  database, firebase
Firebase Android Sdk
Firebase Android SDK
Stars: ✭ 1,704 (+647.37%)
Mutual labels:  firebase, firebase-database
Firebase Php
Unofficial Firebase Admin SDK for PHP
Stars: ✭ 1,657 (+626.75%)
Mutual labels:  firebase, firebase-database
React Mobx Firebase Authentication
🔥Boilerplate Project for Authentication with Firebase in React and MobX
Stars: ✭ 111 (-51.32%)
Mutual labels:  firebase, firebase-database
Expo Native Firebase
🔥 Native Firebase Expo App (iOS, Android) Demo for Firestore, Notifications, Analytics, Storage, Messaging, Database 🚨
Stars: ✭ 197 (-13.6%)
Mutual labels:  firebase, firebase-database
React Firebase Hooks
React Hooks for Firebase.
Stars: ✭ 2,227 (+876.75%)
Mutual labels:  firebase, firebase-database
Vue Trello
Trello clone with Vue.js for educational purposes
Stars: ✭ 185 (-18.86%)
Mutual labels:  firebase, firebase-database
Firebase Esp32
ESP32 Firebase RTDB Arduino Library
Stars: ✭ 204 (-10.53%)
Mutual labels:  firebase, firebase-database
Fcm Toolbox
📲 Firebase Cloud Messaging toolbox
Stars: ✭ 217 (-4.82%)
Mutual labels:  firebase, firebase-database
React Native Firebase
🔥 A well-tested feature-rich modular Firebase implementation for React Native. Supports both iOS & Android platforms for all Firebase services.
Stars: ✭ 9,674 (+4142.98%)
Mutual labels:  database, firebase

Version Platform Downloads

Salada 🍐

Salad is a Model for Firebase database. It can handle Snapshot of Firebase easily.

Make a Model with Salada

  • [x] You no longer need to create a server.
  • [x] You no longer need to make a mock.
  • [x] It operates in real time.
  • [x] You can create a reactive UI.

Requirements ❗️

Installation ⚙

CocoaPods

  • Insert pod 'Salada' to your Podfile.
  • Run pod install.

Usage 👀

Model

Model of the definition is very simple. To inherit the Object.

class User: Object {

    dynamic var name: String?
    dynamic var age: Int = 0
    dynamic var gender: String?
    dynamic var groups: Set<String> = []
    dynamic var items: [String] = []
    dynamic var url: URL?
    dynamic var birth: Date?
    dynamic var thumbnail: File?
    dynamic var followers: Relation<User> = []
}

When you want to create a property that you want to ignore.

// Group
class Group: Object {
    dynamic var name: String?
    dynamic var users: Set<String> = []
}

Property

Property are four that can be specified in Salada.

Property Description
String Simple string.
Number(Int, UInt, Double ...) Simple number.
URL URL
Date date
Array<String> Array of strings.
Set <String> Array of strings. Set is used in relationships.
Reation<Object> Reference
[String: Any] Object
AnyObject Use encode, decode function.

⚠️ Bool, Int, Float, and Double are not supported optional types.

Save and Update

Do not forget to change the database rules.

{
  "rules": {
    ".read": true,
    ".write": true
  }
}
// This rule is dangerous. Please change the rules according to the model

https://firebase.google.com/docs/database/security/

The new model is stored in the save() or save(completion: ((NSError?, FIRDatabaseReference) -> Void)?). It is updated automatically when you change the property Model that has already been saved.

let group: Group = Group()
group.name = "iOS Development Team"
group.save { (error, ref) in

    do {
        let user: User = User()
        user.name = "john appleseed"
        user.gender = "man"
        user.age = 22
        user.items = ["Book", "Pen"]
        user.groups.insert(ref.key)
        user.save({ (error, ref) in
            group.users.insert(ref.key) // It is updated automatically
        })
    }

    do {
        let user: User = User()
        user.name = "Marilyn Monroe"
        user.gender = "woman"
        user.age = 34
        user.items = ["Rip"]
        user.groups.insert(ref.key)
        user.save({ (error, ref) in
            group.users.insert(ref.key) // It is updated automatically
        })
    }

}

Retrieving Data

  • observeSingle(eventType: FIRDataEventType, block: ([Tsp]) -> Void)
  • observeSingle(id: String, eventType: FIRDataEventType, block: (Tsp) -> Void)
User.observeSingle(FIRDataEventType.Value) { (users) in
    users.forEach({ (user) in
        // do samething
        if let groupId: String = user.groups.first {
            Group.observeSingle(groupId, eventType: .Value, block: { (group) in
                // do samething
            })
        }
    })
}

Remove Data


if let groupId: String = user.groups.first {
    Group.observeSingle(groupId, eventType: .Value, block: { (group) in
        group.remove()
    })
}

Custom Property

class User: Salada.Object {

    override class var _version: String {
        return "v1"
    }

    dynamic var name: String?
    dynamic var age: Int = 0
    dynamic var gender: String?
    dynamic var groups: Set<String> = []
    dynamic var items: [String] = []
    dynamic var location: CLLocation?
    dynamic var url: URL?
    dynamic var birth: Date?
    dynamic var thumbnail: File?
    dynamic var cover: File?
    dynamic var type: UserType = .first

    var tempName: String?

    override var ignore: [String] {
        return ["tempName"]
    }

    override func encode(_ key: String, value: Any?) -> Any? {
        if key == "location" {
            if let location = self.location {
                return ["latitude": location.coordinate.latitude, "longitude": location.coordinate.longitude]
            }
        } else if key == "type" {
            return self.type.rawValue as AnyObject?
        }
        return nil
    }

    override func decode(_ key: String, value: Any?) -> Any? {
        if key == "location" {
            if let location: [String: Double] = value as? [String: Double] {
                self.location = CLLocation(latitude: location["latitude"]!, longitude: location["longitude"]!)
                return self.location
            }
        } else if key == "type" {
            if let type: Int = value as? Int {
                self.type = UserType(rawValue: type)!
                return self.type
            }
        }
        return nil
    }
}

Upload file

You can easily save the file if you use the File. File saves the File in FirebaseStorage.

Do not forget to change the storage rules.

let user: User = User()
let image: UIImage = UIImage(named: "Salada")!
let data: NSData = UIImagePNGRepresentation(image)!
let thumbnail: File = File(data: data, mimeType: .jpeg)
user.thumbnail = thumbnail
user.save({ (error, ref) in
    // do something
})
let image: UIImage = #imageLiteral(resourceName: "salada")
let data: Data = UIImageJPEGRepresentation(image, 1)!
let file: File = File(data: data, mimeType: .jpeg)
item.file = file
let task: FIRStorageUploadTask = item.file?.save(completion: { (metadata, error) in
    if let error = error {
        print(error)
        return
    }
})

Download file

Download of File is also available through the File.

guard let user: User = self.datasource?.objectAtIndex(indexPath.item) else { return }
user.thumbnail?.dataWithMaxSize(1 * 2000 * 2000, completion: { (data, error) in
    if let error: NSError = error {
        print(error)
        return
    }
    cell.imageView?.image = UIImage(data: data!)
    cell.setNeedsLayout()
})

FirebaseUI makes it even easier to access.

# Only pull in FirebaseUI Storage features
pod 'FirebaseUI/Storage', '~> 3.0'
User.observeSingle(friend, eventType: .value, block: { (user) in
    if let user: User = user as? User {
        if let ref: FIRStorageReference = user.thumbnail?.ref {
            cell.imageView.sd_setImage(with: ref, placeholderImage: #imageLiteral(resourceName: "account_placeholder"))
        }
    }
 })

Relationship

Please use Relation to create a relationship between models. It can be defined by inheriting Relation class.

class Follower: Relation<User> {
    override class var _name: String {
        return "follower"
    }
}
class User: Object {
    let followers: Follower = []
}

Data Source

See SaladBar.

For example

// ViewController Sample

var dataSource: DataSource<User>?

override func viewDidLoad() {
    super.viewDidLoad()
    
    let options: Options = Options()
    options.limit = 10
    options.sortDescirptors = [NSSortDescriptor(key: "age", ascending: false)]
    self.dataSource = DataSource(reference: User.databaseRef, options: options, block: { [weak self](changes) in
        guard let tableView: UITableView = self?.tableView else { return }
        
        switch changes {
        case .initial:
            tableView.reloadData()
        case .update(let deletions, let insertions, let modifications):
            tableView.beginUpdates()
            tableView.insertRows(at: insertions.map { IndexPath(row: $0, section: 0) }, with: .automatic)
            tableView.deleteRows(at: deletions.map { IndexPath(row: $0, section: 0) }, with: .automatic)
            tableView.reloadRows(at: modifications.map { IndexPath(row: $0, section: 0) }, with: .automatic)
            tableView.endUpdates()
        case .error(let error):
            print(error)
        }
    })
}

// TableViewDatasource
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.dataSource?.count ?? 0
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell: TableViewCell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell", for: indexPath) as! TableViewCell
    configure(cell, atIndexPath: indexPath)
    return cell
}

func configure(_ cell: TableViewCell, atIndexPath indexPath: IndexPath) {
    cell.disposer = self.dataSource?.observeObject(at: indexPath.item, block: { (user) in
        cell.imageView?.contentMode = .scaleAspectFill
        cell.textLabel?.text = user?.name
    })
}

private func tableView(_ tableView: UITableView, didEndDisplaying cell: TableViewCell, forRowAt indexPath: IndexPath) {
    cell.disposer?.dispose()
}

func tableView(_ tableView: UITableView, canPerformAction action: Selector, forRowAt indexPath: IndexPath, withSender sender: Any?) -> Bool {
    return true
}

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete {
        self.dataSource?.removeObject(at: indexPath.item, cascade: true, block: { (key, error) in
            if let error: Error = error {
                print(error)
            }
        })
    }
}

Observe

You can receive data changes through observation.
And easy to manage observation using Disposer.

class ViewController: UIViewController {
    private var disposer: Disposer<User>?

    override func viewDidLoad() {
        super.viewDidLoad()
        disposer = User.observe(userID, eventType: .value) { user in
             //...
        }
    }

    deinit {
        // ... auto remove observe internal disposer when it deinitialized.
        // or manually and clearly dispose
        // disposer?.dispose()
    }
}

Salada has Disposer, AnyDisposer and NoDisposer.
See details: Disposer.swift

Reference

  • Salada Firebase model framework.
  • Tong Tong is library for using ElasticSearch with Swift.
  • dressing Dressing provides the functionality of CloudFunctions to connect Firebase and ElasticSearch.

Contributing

We welcome any contributions. See the CONTRIBUTING file for how to get involved.

Saladaは日本製です。日本人のコントリビューター大歓迎🎉

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].