{"id":15059445,"url":"https://github.com/thomasweiser/elmfire","last_synced_at":"2025-08-18T09:12:50.124Z","repository":{"id":30176874,"uuid":"33727367","full_name":"ThomasWeiser/elmfire","owner":"ThomasWeiser","description":"Firebase Bindings for Elm","archived":false,"fork":false,"pushed_at":"2018-03-21T06:38:05.000Z","size":423,"stargazers_count":211,"open_issues_count":7,"forks_count":16,"subscribers_count":22,"default_branch":"master","last_synced_at":"2025-04-10T05:10:47.190Z","etag":null,"topics":["elm","elmfire","firebase"],"latest_commit_sha":null,"homepage":"http://package.elm-lang.org/packages/ThomasWeiser/elmfire/latest","language":"Elm","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ThomasWeiser.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-04-10T12:30:46.000Z","updated_at":"2024-11-19T14:36:41.000Z","dependencies_parsed_at":"2022-07-25T18:30:08.123Z","dependency_job_id":null,"html_url":"https://github.com/ThomasWeiser/elmfire","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/ThomasWeiser/elmfire","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThomasWeiser%2Felmfire","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThomasWeiser%2Felmfire/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThomasWeiser%2Felmfire/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThomasWeiser%2Felmfire/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ThomasWeiser","download_url":"https://codeload.github.com/ThomasWeiser/elmfire/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ThomasWeiser%2Felmfire/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270969091,"owners_count":24677244,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-18T02:00:08.743Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["elm","elmfire","firebase"],"created_at":"2024-09-24T22:43:58.057Z","updated_at":"2025-08-18T09:12:50.085Z","avatar_url":"https://github.com/ThomasWeiser.png","language":"Elm","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ElmFire: Use the Firebase API in Elm\n\nVirtually all features of the [Firebase Web API](https://www.firebase.com/docs/web/) are exposed as a [library](http://package.elm-lang.org/packages/ThomasWeiser/elmfire/latest) for [Elm](http://elm-lang.org/):\n\n- Setting, removing and modifying values\n- Transactions\n- Querying data, both one-time and per subscription\n- Complex queries with sorting, filtering and limiting\n- Authentication\n- User management\n- Offline capabilities\n\nIn addition to these base functions the package __[elmfire-extra](http://package.elm-lang.org/packages/ThomasWeiser/elmfire-extra/latest)__ provides a higher-level synchronization API, which allows you to treat your Firebase data like a local Elm-Dict.\n\n_Demo application for these APIs: [Collaborative TodoMVC](https://github.com/ThomasWeiser/todomvc-elmfire)_\n\n---\n\n_This library currently targets Elm version 0.16._\n\n_A new version with an [effect manager](https://guide.elm-lang.org/effect_managers/index.html) for Elm 0.17/0.18 is under development. Please stay tuned!_\n\n---\n\n## API Usage\n\nThe API design corresponds closely to the targeted Firebase JavaScript API.\nPlease refer to the [original documentation](https://www.firebase.com/docs/web/) for further discussions of the concepts.\n\nIn the following we give a short overview of the API.\nDetailed documentation is embedded in the source code.\n\n### Constructing Firebase Locations\n\nTo refer to a Firebase path use a `Location`.\nIt can be built with the following functions:\n\n```elm\n-- Location is an opaque type.\nfromUrl  : String -\u003e Location\nsub      : String -\u003e Location -\u003e Location\nparent   : Location -\u003e Location\nroot     : Location -\u003e Location\npush     : Location -\u003e Location\nlocation : Reference -\u003e Location\n```\n\nThese are all pure functions.\nThey don't touch a real Firebase until the resulting location is used in one of the tasks outlined below.\n\nExample:\n\n```elm\nlocation : Location\nlocation =\n  fromUrl \"https://elmfire.firebaseio-demo.com/test\"\n    |\u003e parent\n    |\u003e sub \"anotherTest\"`\n    |\u003e push\n```\n\n### References to Locations\n\nMost actions on a Firebase location return a reference to that location.\nLikewise, query results contain a reference to the location of the reported value.\n\nReferences can inform about the key or the complete URL of the referred location.\nAnd a reference may be converted back to a location, which can be used in a new task.\n\nThere is a special task to open a location without modifying or querying it,\nwhich results in a reference if the location is valid.\nIt's generally not necessary to explicitly open a constructed location,\nbut it may be used to check the validity of a location or to cache Firebase references.\n\n```elm\n-- Reference is an opaque type\nkey      : Reference -\u003e String\ntoUrl    : Reference -\u003e String\nlocation : Reference -\u003e Location\nopen     : Location -\u003e Task Error Reference\n```\n\n### Modifying Values\n\n```elm\nset             : Value -\u003e Location -\u003e Task Error Reference\nsetWithPriority : Value -\u003e Priority -\u003e Location -\u003e Task Error Reference\nsetPriority     : Priority -\u003e Location -\u003e Task Error Reference\nupdate          : Value -\u003e Location -\u003e Task Error Reference\nremove          : Location -\u003e Task Error Reference\n```\n\nThese tasks complete when synchronization to the Firebase servers has completed.\nOn success they result in a Reference to the modified location.\nThey result in an error if the location is invalid or if you have no permission to modify the data.\n\nValues are given as Json values, i.e. `Json.Encode.Value`.\n\nExample:\n\n```elm\nport write : Task Error ()\nport write =\n  set (Json.Encode.string \"new branch\") (push location)\n  `andThen`\n  (\\ref -\u003e ... ref.key ... )\n```\n\n### Transactions\n\nAtomic modifications of the data at a location can be achieved by transactions.\n\nA transaction takes an update function that maps the previous value to a new value.\nIn case of a conflict with concurrent updates by other clients\nthe update function is called repeatedly until no more conflict is encountered.\n\n```elm\ntransaction : (Maybe Value -\u003e Action) -\u003e\n              Location -\u003e\n              Bool -\u003e\n              Task Error (Bool, Snapshot)\ntype Action = Abort | Remove | Set Value\n```\n\nExample:\n\n```elm\nport trans : Task Error -\u003e Task Error ()\nport trans =\n  transaction\n    ( \\maybeVal -\u003e case maybeVal of\n        Just value -\u003e\n          case Json.Decode.decodeValue Json.Decode.int value of\n            Ok counter -\u003e Set (Json.Encode.int (counter + 1))\n            _          -\u003e Abort\n        Nothing -\u003e\n          Set (Json.Encode.int 1)\n    ) location False\n  `andThen`\n  (\\(committed, snapshot) -\u003e ... )\n```\n\n### Querying\n\n```elm\nonce        : Query -\u003e Location -\u003e Task Error Snapshot\nsubscribe   : (Snapshot -\u003e Task x a) -\u003e\n              (Cancellation -\u003e Task y b) -\u003e\n              Query -\u003e\n              Location -\u003e\n              Task Error Subscription\nunsubscribe : Subscription -\u003e Task Error ()\n```\n\nUse `once` to listen to exactly one event of the given type.\n\nThe first parameter specifies the event to listen to: `valueChanged`, `childAdded`, `childChanged`, `childRemoved` or `childMoved`.\nAdditionally, this parameter may also specify ordering, filtering and limiting of the query (see below).\nIf you don't need these options a simple query specification is `valueChanged noOrder`.\n\nThe second parameter references the queried location.\n\nUse `subscribe` to start a continuing query of the specified events.\nSubscription queries return a arbitrary number of data messages,\nwhich are reported via running a supplied task.\n\nThe first parameter of `subscribe` is a function used to construct that task from a data message.\n\nThe second parameter is a function used to construct a task that is run when the query gets canceled.\n\nThe third and fourth parameter of `subscribe` are the same as the first two of `once`.\n\nOn success the `subscribe` task returns a Subscription, an identifier that can be used to match the corresponding responses and to cancel the query.\n\n```elm\ntype alias Snapshot =\n  { subscription: Subscription\n  , key: String\n  , reference: Reference\n  , existing: Bool\n  , value: Value\n  , prevKey: Maybe String\n  , priority: Priority\n  }\ntype Cancellation\n  = Unsubscribed Subscription\n  | QueryError Subscription Error\n```\n\nA `Snapshot` carries the resulting `Value` (as Json) among other information,\ne.g. the corresponding `Subscription` identifier.\n\nIn queries of type `valueChanged` the result may be that there is no value at the queried location.\nIn this case `existing` will be `False` and value will be the Json value of `null`.\n\n`key` corresponds to the last part of the path.\nIt is the empty string for the root.\nKeys are relevant notably for child queries.\n\nExample:\n\n```elm\nresponses : Signal.Mailbox (Maybe Snapshot)\nresponses = Signal.mailbox Nothing\n\nport query : Task Error Subscription\nport query =\n  subscribe\n    (Signal.send responses.address \u003c\u003c Just)\n    (always (Task.succeed ()))\n    (childAdded noOrder noLimit)\n    (fromUrl \"https:...firebaseio.com/...\")\n\n... = Signal.map\n        (\\response -\u003e case response of\n            Nothing -\u003e ...\n            Just snapshot -\u003e ...\n        )\n        responses.signal\n```\n\n### Ordering, Filtering and Limiting Queries\n\nQuery results can be ordered (by value, by a child's value, by key or by priority),\nand then filtered by giving a start and/or end value within that order,\nand limited to the first or last certain number of children.\n\nExample queries to be used in `once` and `subscribe`:\n\n```elm\nchildAdded noOrder\nchildAdded (orderByValue noRange noLimit)\nchildAdded (orderByChild \"size\" noRange noLimit)\nchildAdded (orderByKey noRange noLimit)\nchildAdded (orderByPriority noRange (limitToFirst 2))\nchildAdded (orderByValue (startAt (Json.Encode.string \"foo\")) noLimit)\nchildAdded (orderByValue (startAt (Json.Encode.string \"foo\")) (limitToLast 10))\nchildAdded (orderByChild \"size\" (equalTo (Json.Encode.int 42)) noLimit)\nchildAdded (orderByKey (endAt \"k\") noLimit)\nchildAdded (orderByPriority (startAt (NumberPriority 17, Just \"k\")) noLimit)\n```\n\nWhen doing ordered `valuedChanged` queries it may be useful to map the result\nto a list to conserve the ordering:\n\n```elm\ntoSnapshotList : Snapshot -\u003e List Snapshot\ntoValueList    : Snapshot -\u003e List JE.Value\ntoKeyList      : Snapshot -\u003e List String\ntoPairList     : Snapshot -\u003e List (String, JE.Value)\n```\n\n### Authentication\n\nThe sub-module ElmFire.Auth provides all authentication and user management functions\nthat are offered by Firebase.\n\nSome example tasks:\n\n```elm\nimport ElmFire.Auth exposing (..)\n\n-- create a new user-account with email and password\nuserOperation (createUser \"me@some.where\" \"myPassword\")\n\n-- login with with email and password\nauthenticate loc [rememberSessionOnly] (withPassword \"me@some.where\" \"myPassword\")\n\n-- login with with github account\nauthenticate loc [] (withOAuthPopup \"github\")\n\n-- watch for logins and logouts\nsubscribeAuth\n  (\\maybeAuth -\u003e case maybeAuth of\n    Just auth -\u003e ... auth.uid ...\n    Nothing   -\u003e ... -- not authenticated\n  )\n  loc\n```\n\n### Offline Capabilities\n\n- Detecting connection state changes: `subscribeConnected`\n- Manually disconnect and reconnect:\n  `goOffline`, `goOnline`\n- Managing presence:\n  `onDisconnectSet`, `onDisconnectSetWithPriority`, `onDisconnectUpdate`,\n  `onDisconnectRemove`, `onDisconnectCancel`\n- Handling latency:\n  `subscribeServerTimeOffset`, `serverTimeStamp`\n\n## Examples\n\nThere is a basic example app in `example/src/Example.elm`. To build it:\n\n```sh\ncd example\nmake all open\n```\n\nAlternatively without using `make`:\n\n```sh\ncd example\nelm make --output Example.html src/Example.elm\n```\n\n### TodoMVC\n\nA more extensive example is\n[this implementation of TodoMVC](https://github.com/ThomasWeiser/todomvc-elmfire)\nas a collaborative real-time app.\n\n## Testing\n\nThere is a testing app, living in the directory `test`, that covers most of the code.\nIt runs a given sequence of tasks on the Firebase API and logs these steps along with the several results.\n\nThis app uses a small ad-hoc testing framework for task-based code.\n\nThere is a Makefile to build the app. On most Unix-like systems a `cd test; make all open` should do the trick.\n\nAn older, still functional testing app lives in the directory `demo`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthomasweiser%2Felmfire","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthomasweiser%2Felmfire","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthomasweiser%2Felmfire/lists"}