How to check Item exists in Firebase Database? - react-native-firebase - firebase

Currently, I am using https://github.com/invertase/react-native-firebase for my project. I have a custom database for users and I want to check if the user exists or not by email.
Here is a screenshot of the database:

Here's a generic firebase method but you may need to reconfigure the method to suit your data structure. Please refer to the official docs if you wish to know more.
firebase.database()
.ref(`/users`)
.orderByChild("email")
.equalTo(email)
.once("value")
.then(snapshot => {
if (snapshot.val()) {
// data exist, do something else
}
})
You can also query the registration status with hasChild method. Refer to your root path and query with .once and check the result returned.
export function checkUserExist(email) {
return(dispatch) => {
firebase.database().ref(`/ExistingUser/`)
.once('value', snapshot => {
if(snapshot.hasChild(email)) {
dispatch({
type: FIREBASE_USER_EXISTED
});
} else {
dispatch({
type: FIREBASE_USER_NOT_EXISTED,
});
}
});
}
}
Another preferred method would be using the fetchProvidersForEmail method provided by Firebase. It takes an email and returns a promise that resolves with the list of providers linked to that email if it is already registered, refer here.
Is there a good reason to store users credential in your database? In my daily practice, I would use the createUserWithEmailAndPassword provided by Firebase for security purposes, refer here. Just make sure rules are defined properly to prevent unauthorized access.

Related

firebase auth token from Graphcool

can I generate a custom auth token, for use with a third party, with a resolver in graph.cool? something like this??
type FirebaseTokenPayload {
token: String!
}
extend type Query {
FirebaseToken(userIdentifier: String!): FirebaseTokenPayload
}
const fb = require('myNodeFirebaseAuthLib')
module.exports = event => fb.generateTokenWithPayload({ id: event.data.userId })
Authentication required - restrict who can read data in fields: Permission query:
query ($user_id: ID!, $node_firebaseIdentifier: String) {
SomeUserExists(filter: {
id: $user_id ,
firebaseIdentifier: $node_firebaseIdentifier
})
}
--
I think this question boils down two parts
"is it possible to install node modules in the graph.cool instance -- or for that sort of thing do we need to use a webhook" -- if it must be a webhook, what is the flow of identity verification and how do I pass the payload parameters ?
"can we add permissions queries and authentication to resolvers?"
notes, addendums:
according to this alligator.io blog post, it seems that using the Graphcool framework, you can install node modules! So, I wouldn't need to use a webhook. -- However, that is with an ejected app. I lose auth0 authentication that way -- the template does not produce a createUser and singinUser that works with the same auth0 data that the integration offers.
I forgot to post the answer to this - I had to eject graphcool, I could not use any node_modules I thought to try in my custom functions.

Firebase - Saving data

I have a question regarding the firebase.
I'm developing an app where there are three screens: the 'registration screen' where the user will create an account with email and password. The 'building profile screen', where the user will answer some questions to be implemented in his profile, (such as "What's your name?"). And finally the 'profile screen', where the user information will be displayed, such as the user name.
On the 'registration screen' I'm having no problem, the user fills in the email input and password input, and by clicking "create account", calling .createUserWithEmailAndPassword, the user account is created and it is taken to the 'building profile screen'. The question I'm having is in the 'building profile screen'. My question is: How can I save the user name and other data?
I read some articles on the subject but I had difficulty understanding. Can any of you guys help me with this?
You're going to want to create a node or multiple nodes in firebase for each user to hold their user-specific information. The database structure could be uniform like so:
users: {
uid_a: {
username: 'uid_as_username',
email: 'uid_as_email',
name: 'uid_as_name',
other_attribute: 'uid_as_other_attribute_value'
[,...]
},
uid_b: {
username: 'uid_bs_username',
email: 'uid_bs_email',
name: 'uid_bs_name',
other_attribute: 'uid_bs_other_attribute_value'
[,...]
}
[,...]
}
or split up like so:
usernames: {
uid_a: 'uid_as_username',
uid_b: 'uid_bs_username'
[,...]
},
emails: {
uid_a: 'uid_as_email',
uid_b: 'uid_bs_email'
[,...]
},
names: {
uid_a: 'uid_as_name',
uid_b: 'uid_bs_name'
[,...]
},
other_attribute: {
uid_a: 'uid_as_other_attribute_value',
uid_b: 'uid_bs_other_attribute_value'
[,...]
}
Which you choose is a design choice, but thats the idea.
Just complementing #Vincent answer, by default you can store the user name, email and photoUrl within firebase auth (read get user profile: https://firebase.google.com/docs/auth/web/manage-users).
If you need to store more info, like postal address, phonenumbers, and so on, you can create a node in your database like users and store all the data you need. You can even use the same UID created for auth as the ID of your database. This way it would be easier for you to get user infos in the future.
When you just create the user with email and password, you can return the user and add it to your database with a script like this
firebase.database.ref(`Users/${user.uid}`).set({
name: this.state.name,
email: this.state.email,
});
Consider the code above just as an example.
Prefer to use .set() instead of .push(). If you use .push() firebase will create a random id which you will not be able to change. Using .set() you can determine the value of your node.
Hope it helps.
This is taken from the official documentation that might give you clue how to update and fetch data from database.
Set up Firebase Realtime Database for Android
Connect your app to Firebase
Install the Firebase SDK. In the Firebase console, add your app to
your Firebase project. Add the Realtime Database to your app
Add the dependency for Firebase Realtime Database to your app-level
build.gradle file:
compile 'com.google.firebase:firebase-database:11.2.2'
Configure Firebase Database Rules
The Realtime Database provides a declarative rules language that
allows you to define how your data should be structured, how it should
be indexed, and when your data can be read from and written to. By
default, read and write access to your database is restricted so only
authenticated users can read or write data. To get started without
setting up Authentication, you can configure your rules for public
access. This does make your database open to anyone, even people not
using your app, so be sure to restrict your database again when you
set up authentication.
Write to your database
Retrieve an instance of your database using getInstance() and
reference the location you want to write to.
// Write a message to the database
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("message");
myRef.setValue("Hello, World!");
You can save a range of data types to the database this way, including
Java objects. When you save an object the responses from any getters
will be saved as children of this location.
Read from your database
To make your app data update in realtime, you should add a
ValueEventListener to the reference you just created.
The onDataChange() method in this class is triggered once when the
listener is attached and again every time the data changes, including
the children.
// Read from the database
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// This method is called once with the initial value and again
// whenever data at this location is updated.
String value = dataSnapshot.getValue(String.class);
Log.d(TAG, "Value is: " + value);
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.w(TAG, "Failed to read value.", error.toException());
}
});

Meteor & account-base - how to get data for different users

I have basic project in Meteor created from Meteor-admin stub: (https://github.com/yogiben/meteor-admin)
I need to display avatars for all users, not only current one.
For displaying user's avatar I need his email address. (I am using utilities:avatar https://atmospherejs.com/utilities/avatar)
Question: what adjustments to project should I make to be able to access other users' data?
It probably has something to do with publishing users.
At the moment I have:
{{> avatar user=getAuthor shape="circle" size="small"}}
getAuthor: ->
console.log 'Owner:'
console.log #owner
user = Meteor.users.findOne(#owner)
console.log user
user
This correctly prints Owner: #owner (id) for all users, but user object is only populated for current user.
I also have this code in server-side:
Meteor.publishComposite 'user', ->
find: ->
Meteor.users.find _id: #userId
children: [
find: (user) ->
_id = user.profile?.picture or null
ProfilePictures.find _id: _id
]
(children / ProfilePicture are irrelevent)
I think account-base library turns publishing off or something? Thanks for help!
Bonus question: I would like to access only some info about an user (email address).
If you remove the package autopublish, you need to specify explicitly what the server sends to the client. You can do this via Meteor.publish and Meteor.subscribe.
For instance, to publish the email addresses of all users you could do:
if (Meteor.isServer) {
Meteor.publish('emailAddresses', function() {
return Meteor.users.find({}, {
fields: {
'email': 1
}
});
});
}
After that, you need to subscribe to the publication on the client:
if (Meteor.isClient) {
Meteor.subscribe("emailAddresses");
}
Read more about Meteor's publish and subscribe functionality.
Having collection: Meteor.users
To access other users data just publish it on the server-side:
Meteor.publish 'userData', ->
Meteor.users.find()
On client side you don't have to use any userData reference. Just access it:
Meteor.users.findOne(someId)
To allow access to only specific information, publish it with fields parameter:
Meteor.publish 'userData', ->
Meteor.users.find({},{fields: {'_id', 'emails', 'username'}})

Publishing different data for different users

I'm trying to publish all users to admins only but ommitting certain data (In this case an API key which is supposed to be "private" to each user, I realize that the admin can most likely check the database but let's ignore the security implications for now).
So the basic idea is that a user can see his own profile completely and no one else. An admin can see his own complete profile and a censored version of all other user's profiles. For this I have the following publish code:
Meteor.publish('currentUser', function() {
return Meteor.users.find({_id: this.userId}, {fields: {'profile.apiKey': true}});
});
Meteor.publish('allUsers', function() {
var currentUser = Meteor.users.findOne(this.userId);
return currentUser && currentUser.profile.admin ?
Meteor.users.find({}, {sort: ['username', 'asc'], fields: {'profile.apiKey': false}}) : null;
});
The problem is that the apiKey field doesn't get published after logging in. Ie. if I simply login as an admin the admin's apiKey won't be available until the page is reloaded. Removing the restriction from the 'allUsers' publish function solves the issue so it must have something to do with this. Is there any way to force Meteor to reload the subscriptions after a login?

How can i restrict access to my firebase so that only I - the owner can access it

I find my self very confused.
My task is very simple, i want to use Firebase with node.js so that only i will be able to access the base.
Usually services gives a sort of a key so that only the owner can login to the base.
Why isn't this possible? I don't need any authentication for users in my case, so i find the documentation very confusing since i don't need any authentication except for not allowing anyone else than me to access the base.
This is not supposed to be done via a 3rd party provider, this should be allowed directly from your service.
Please help.
Ok. so i managed to find the solution.
In you account you have the tab security rules which you should change to:
{
"rules": {
".read": false,
".write": false
}
}
Now go to the tab Secrets and you will find your auth key.
Now in the node.js code do:
var dataRef = new Firebase("https://<YOUR-FIREBASE>.firebaseio.com/");
// Log me in.
dataRef.auth(AUTH_TOKEN, function(error) {
if(error) {
console.log("Login Failed!", error);
} else {
console.log("Login Succeeded!");
}
});
This is confused me a little since they are talking about users, but i didn't think of my self (owner) as a user accessing the base.

Resources