Skip to content

Commit e867e18

Browse files
committed
Added README.md
1 parent bff958d commit e867e18

File tree

1 file changed

+375
-0
lines changed

1 file changed

+375
-0
lines changed

README.md

Lines changed: 375 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,375 @@
1+
## Firestack
2+
3+
Firestack makes using the latest [Firebase](http://firebase.com) straight-forward.
4+
5+
## What
6+
7+
Firestack is a _light-weight_ layer sitting atop the native Firebase libraries for iOS and Android (coming soon), deferring to as much of the JavaScript library as possible. For parts of the api that are natively supported by the Firebase JavaScript api, this library acts as a thin proxy to the JS objects, while it provides a native shim to those that are not covered.
8+
9+
## Installing
10+
11+
Install the `npm` package with:
12+
13+
```bash
14+
npm install react-native-firestack --save
15+
```
16+
17+
To use Firestack, we'll need to have a development environment that includes the same prerequisites of Firebase.
18+
19+
### iOS
20+
21+
We need to link the package with our development packaging. We have two options to handle linking:
22+
23+
#### Automatically with [rnpm](https://github.com/rnpm/rnpm)
24+
25+
[rnpm](https://github.com/rnpm/rnpm) is a React Native package manager which can help to automate the process of linking package environments.
26+
27+
```bash
28+
rnpm link
29+
```
30+
31+
#### Manually
32+
33+
If you prefer not to use `rnpm`, we can manually link the package together with the following steps, after `npm install`:
34+
35+
1. In XCode, right click on `Libraries` and find the `Add Files to [project name]`.
36+
37+
![Add library to project](http://d.pr/i/2gEH.png)
38+
39+
2. Add the `node_modules/react-native-firestack/ios/Firestack.xcodeproj`
40+
41+
![Firebase.xcodeproj in Libraries listing](http://d.pr/i/19ktP.png)
42+
43+
3. In the project's "Build Settings" tab in your app's target, add `libFirestack.a` to the list of `Link Binary with Libraries`
44+
45+
![Linking binaries](http://d.pr/i/1cHgs.png)
46+
47+
4. Ensure that the `Build Settings` of the `Firestack.xcodeproj` project is ticked to _All_ and it's `Header Search Paths` include both of the following paths _and_ are set to _recursive_:
48+
49+
1. `$(SRCROOT)/../../react-native/React`
50+
2. `$(SRCROOT)/../node_modules/react-native/React`
51+
52+
![Recursive paths](http://d.pr/i/1hAr1.png)
53+
54+
#### Cocoapods
55+
56+
You can also install `Firestack` as a cocoapod by adding the line to your `ios/Podfile`
57+
58+
```ruby
59+
pod 'Firestack'
60+
```
61+
62+
### Android
63+
64+
Coming soon
65+
66+
## Firebase setup
67+
68+
The Firestack library is intended on making it easy to work with [Firebase](https://firebase.google.com/) and provides a small native shim to the Firebase native code.
69+
70+
To add Firebase to your project, make sure to create a project in the [Firebase console](https://firebase.google.com/console)
71+
72+
![Create a new project](http://d.pr/i/17cJ2.png)
73+
74+
Each platform uses a different setup method after creating the project.
75+
76+
### iOS
77+
78+
After creating a Firebase project, click on the [Add Firebase to your iOS app](http://d.pr/i/3sEL.png) and follow the steps from there.
79+
80+
**[IMPORTANT: Download the config file](https://support.google.com/firebase/answer/7015592)**
81+
82+
Once you download the configuration file, make sure you place it in the root of your Xcode project. Every different Bundle ID (aka, even different project variants needs their own configuration file).
83+
84+
### Android
85+
86+
Coming soon
87+
88+
## Usage
89+
90+
After creating a Firebase project and installing the library, we can use it in our project by importing the library in our JavaScript:
91+
92+
```javascript
93+
import Firestack from 'react-native-firestack'
94+
```
95+
96+
We need to tell the Firebase library we want to _configure_ the project. Firestack provides a way to configure both the native and the JavaScript side of the project at the same time with a single command:
97+
98+
```javascript
99+
const server = new Firestack();
100+
server.configure()
101+
.then(() => console.log("Project configured and ready to boot"));
102+
```
103+
104+
Firestack is broken up into multiple parts, based upon the different API features that Firebase provides.
105+
106+
All methods return a promise.
107+
108+
### Authentication
109+
110+
Firestack handles authentication for us out of the box, both with email/password-based authentication and through oauth providers (with a separate library to handle oauth providers).
111+
112+
#### listenForAuth()
113+
114+
Firebase gives us a reactive method for listening for authentication. That is we can set up a listener to call a method when the user logs in and out. To set up the listener, call the `listenForAuth()` method:
115+
116+
```javascript
117+
server.listenForAuth(function(evt) {
118+
// evt is the authentication event
119+
// it contains an `error` key for carrying the
120+
// error message in case of an error
121+
// and a `user` key upon successful authentication
122+
if (!evt.authenticated) {
123+
// There was an error or there is no user
124+
console.error(evt.error)
125+
} else {
126+
// evt.user contains the user details
127+
console.log('User details', evt.user);
128+
}
129+
})
130+
.then(() => console.log('Listening for authentication changes'))
131+
```
132+
133+
#### unlistenForAuth()
134+
135+
We can remove this listener by calling the `unlistenForAuth()` method. This is important to release resources from our app when we don't need to hold on to the listener any longer.
136+
137+
```javascript
138+
server.unlistenForAuth()
139+
```
140+
141+
#### createUserWithEmail()
142+
143+
We can create a user by calling the `createUserWithEmail()` function. The `createUserWithEmail()` accepts two parameters, an email and a password.
144+
145+
```javascript
146+
server.createUserWithEmail('ari@fullstack.io', '123456')
147+
.then((user) => {
148+
console.log('user created', user)
149+
})
150+
.catch((err) => {
151+
console.error('An error occurred', err);
152+
})
153+
```
154+
155+
#### signInWithEmail()
156+
157+
To sign a user in with their email and password, use the `signInWithEmail()` function. It accepts two parameters, the user's email and password:
158+
159+
```javascript
160+
server.signInWithEmail('ari@fullstack.io', '123456')
161+
.then((user) => {
162+
console.log('User successfully logged in', user)
163+
})
164+
.catch((err) => {
165+
console.error('User signin error', err);
166+
})
167+
```
168+
169+
#### signInWithProvider()
170+
171+
We can use an external authentication provider, such as twitter/facebook for authentication. In order to use an external provider, we need to include another library.
172+
173+
...
174+
175+
### reauthenticateWithCredentialForProvider()
176+
177+
...
178+
179+
#### updateUserEmail()
180+
181+
We can update the current user's email by using the command: `updateUserEmail()`. It accepts a single argument: the user's new email:
182+
183+
```javascript
184+
server.updateUserEmail('ari+rocks@fullstack.io')
185+
.then((res) => console.log('Updated user email'))
186+
.catch(err => console.error('There was an error updating user email'))
187+
```
188+
189+
#### updateUserPassword()
190+
191+
We can update the current user's password using the `updateUserPassword()` method. It accepts a single parameter: the new password for the current user
192+
193+
```javascript
194+
server.updateUserPassword('somethingReallyS3cr3t733t')
195+
.then(res => console.log('Updated user password'))
196+
.catch(err => console.error('There was an error updating your password'))
197+
```
198+
199+
### sendPasswordResetWithEmail()
200+
201+
To send a password reset for a user based upon their email, we can call the `sendPasswordResetWithEmail()` method. It accepts a single parameter: the email of the user to send a reset email.
202+
203+
```javascript
204+
server.sendPasswordResetWithEmail('ari+rocks@fullstack.io')
205+
.then(res => console.log('Check your inbox for further instructions'))
206+
.catch(err => console.error('There was an error :('))
207+
```
208+
209+
#### updateUserProfile()
210+
211+
To update the current user's profile, we can call the `updateUserProfile()` method.
212+
213+
It accepts a single parameter:
214+
215+
* object which contains updated key/values for the user's profile. Possible keys are listed [here](https://firebase.google.com/docs/auth/ios/manage-users#update_a_users_profile).
216+
217+
```javascript
218+
server.updateUserProfile({
219+
displayName: 'Ari Lerner'
220+
})
221+
.then(res => console.log('Your profile has been updated'))
222+
.catch(err => console.error('There was an error :('))
223+
```
224+
225+
#### deleteUser()
226+
227+
It's possible to delete a user completely from your account on Firebase. Calling the `deleteUser()` method will take care of this for you.
228+
229+
```javascript
230+
server.deleteUser()
231+
.then(res => console.log('Sad to see you go'))
232+
.catch(err => console.error('There was an error - Now you are trapped!'))
233+
```
234+
235+
#### signOut()
236+
237+
To sign the current user out, use the `signOut()` method. It accepts no parameters
238+
239+
```javascript
240+
server.signOut()
241+
.then(res => console.log('You have been signed out'))
242+
.catch(err => console.error('Uh oh... something weird happened'))
243+
```
244+
245+
#### getCurrentUser()
246+
247+
Although you _can_ get the current user using the `getCurrentUser()` method, it's better to use this from within the callback function provided by `listenForAuth()`. However, if you need to get the current user, call the `getCurrentUser()` method:
248+
249+
```javascript
250+
server.getCurrentUser()
251+
.then(user => console.log('The currently logged in user', user))
252+
.catch(err => console.error('An error occurred'))
253+
```
254+
255+
### Analytics
256+
257+
Wouldn't it be nice to send analytics about your app usage from your users? Well, you totally can! The Firebase analytics console is incredibly useful and Firestack has a method for interacting with it. You can send any event with contextual information, which automatically includes the currently logged in user using the `logEventWithName()` method. It accepts two parameters: the name of the event and an object containing any contextual information. The values should be serializable (i.e. no complex instance objects).
258+
259+
#### logEventWithName()
260+
261+
```javascript
262+
server.logEventWithName("launch", {
263+
'screen': 'Main screen'
264+
})
265+
.then(res => console.log('Sent event named launch'))
266+
.catch(err => console.error('You should never end up here'));
267+
```
268+
269+
### Storage
270+
271+
Firebase's integration with the Google platform expanded it's features to include hosting user-generated files, like photos. Firestack provides a thin layer to handle uploading files to Firebase's storage service.
272+
273+
#### setStorageUrl()
274+
275+
In order to store anything on Firebase, we need to set the storage url provided by Firebase. This can be set by using the `setStorageUrl()` method. Your storageUrl can be found on the firebase console.
276+
277+
![Storage url](http://d.pr/i/1lKjQ.png)
278+
279+
The `setStorageUrl()` method accepts a single parameter: your root storage url.
280+
281+
```javascript
282+
server.setStorageUrl(`gs://${config.firebase.storageBucket}`)
283+
.then(() => console.log('The storage url has been set'))
284+
.catch(() => console.error('This is weird: something happened...'))
285+
```
286+
287+
#### uploadFile()
288+
289+
We can upload a file using the `uploadFile()` method. Using the `uploadFile()` method, we can set the name of the destination file, the path where we want to store it, as well as any metadata along with the file.
290+
291+
```javascript
292+
server.uploadFile(`photos/${auth.user.uid}/${filename}`, path, {
293+
contentType: 'image/jpeg',
294+
contentEncoding: 'base64',
295+
})
296+
.then((res) => console.log('The file has been uploaded'))
297+
.catch(err => console.error('There was an error uploading the file', err))
298+
```
299+
300+
To upload camera photos, we can combine this method with the `react-native-camera` plugin, for instance:
301+
302+
```javascript
303+
this.camera.capture()
304+
.then(({path}) => {
305+
server.uploadFile(`photos/${auth.user.uid}/${filename}`, path, {
306+
contentType: 'image/jpeg',
307+
contentEncoding: 'base64',
308+
})
309+
})
310+
.catch(err => console.error(err));
311+
```
312+
313+
#### storage attribute
314+
315+
To retrieve a stored file, we can get the url to download it from using the `storage` attribute. This method allows us to call right through to the native JavaScript object provided by the Firebase library:
316+
317+
```javascript
318+
server.storage.ref(photo.fullPath)
319+
.getDownloadURL()
320+
.then(url => {
321+
// url contains the download url
322+
}).catch(err => {
323+
console.error('Error downloading photo', err);
324+
})
325+
```
326+
327+
### Realtime Database
328+
329+
#### database attribute
330+
331+
The native Firebase JavaScript library provides a featureful realtime database that works out of the box. Firestack provides an attribute to interact with the database without needing to configure the JS library.
332+
333+
```javascript
334+
server.storage
335+
.ref(LIST_KEY)
336+
.orderByChild('timestamp')
337+
.on('value', snapshot => {
338+
if (snapshot.val()) {
339+
console.log('The list was updated');
340+
}
341+
});
342+
```
343+
344+
### ServerValue
345+
346+
Firebase provides some static values based upon the server. We can use the `ServerValue` constant to retrieve these. For instance, to grab the TIMESTAMP on the server, use the `TIMESTAMP` value:
347+
348+
```javascript
349+
const timestamp = server.ServerValue.TIMESTAMP
350+
```
351+
352+
### Events
353+
354+
#### on()
355+
356+
We can listen to arbitrary events fired by the Firebase library using the `on()` method. The `on()` method accepts a name and a function callback:
357+
358+
```javascript
359+
server.on('listenForAuth', (evt) => console.log('Got an event'));
360+
```
361+
362+
#### off()
363+
364+
To unsubscribe to events fired by Firebase, we can call the `off()` method with the name of the event we want to unsubscribe.
365+
366+
```javascript
367+
server.off('listenForAuth');
368+
```
369+
370+
371+
## TODO
372+
373+
The following is left to be done:
374+
375+
* Add Android support

0 commit comments

Comments
 (0)