is there a way to manual approve the posts that is being posted to the firebase database through the rules?
the current rule is like this:
{
"rules": {
".read": true,
".write": true
}
}
what I meant is to allow the users to post from into database, but I as an admin control the posts either approve or reject the post from firebase console, is that possible through the rules?
like this Manual approval / rejection of user registration by admin using Firebase
There is nothing built into Firebase for such an approval queue, but you could definitely build it into your app on top of Firebase.
What you essentially do is create a so-called moderation queue, that the users post to. So you end up with two top-level nodes:
posts
post1: ...
post2: ...
post3: ...
pending
post4: ...
post5: ...
The users of your regular app only see the data from /posts.
Then you create a separate app for your moderators, and that app shows the posts in the moderation queue (/pending above) and gives them the option to approve or reject them. If they approve the post, it is added to the actual list of postings that users of the regular app see.
If the app for your moderators is running in a trusted environment, you could consider using the Admin SDK, which ignores the security rules and always has full access to your database. In that case your rules could be as simple as:
{
"rules": {
"posts": {
".read": true
},
"pending": {
"$postid": {
".write": "!data.exists"
}
}
}
}
This allows anyone to read the posts, but only administrators can write them. On the other hand, anyone can write to the moderator queue (as long as they're not overwriting existing data), but only administrators can read from there.
Related
I am trying to create "child" accounts for a registered user.
So, after signing up and authenticating the account I would like to give that user the possibility to register further accounts; for other people to use without the need of an additional email or authentication. These child accounts would be linked back to the main user and that main user can delete/update them.
I am not sure if this is possible with Firebase. I have done some research but have not found a simple or any solution.
Thank you in advance.
The answer is yes, you can do that but there are caveats.
The biggest one is an admin/user situation is that when .createUser is called from the admin account (on the device) it will automatically log IN the createdUser and log OUT the admin. There are a number of posts regarding this behavior.
There are a number of options but one that I would suggest is to leverage the Firebase Admin Auth API which allows you to manage users without having to continually utilize the Firebase Console or do one of the workarounds required on the client side. A node.js example of creating a user looks like this
admin
.auth()
.createUser({
email: 'user#example.com',
emailVerified: false,
phoneNumber: '+11234567890',
password: 'secretPassword',
displayName: 'John Doe',
photoURL: 'http://www.example.com/12345678/photo.png',
disabled: false,
})
.then((userRecord) => {
// See the UserRecord reference doc for the contents of userRecord.
console.log('Successfully created new user:', userRecord.uid);
})
.catch((error) => {
console.log('Error creating new user:', error);
});
I'm using this repo to create a chat system between 2 users in a Rails and React project. I've been able to log the user input into the console, and I have created messages_controller and message_threads_controller according to the repo.
However, I'm unable to persist the message to Rails db and then authenticate a user with Pusher before sending it to Pusher. Mainly because the from_uid, to_uid and thread_uid are not present by the time the message is been sent to Rails. Sending the message to rails like this:
sendMessage = (event) => {
event.preventDefault();
const {message} = this.state;
axios.post('/api/v1/messages', {message: message})
.then((response) => {
console.log(response);
})
console.log('send Message')
this.setState({'message': message});
console.log(this.state.message);
}
In my routes.rb file I have this
resources :messages
get 'threads/:id', to: 'message_threads#index'
post '/pusher/auth', to: 'pusher#auth'
I'm missing some required parameters, this is the error I get.
Pusher::Error - Bad request: Missing required parameter:
The flow according to this tutorial is that the message needs to be persisted first by the rails database before sending it to Pusher.
My question now is how do I produce the extra parameters (from_uid, thread_uid, to_uid) being used on the React side of the app here, to enable messages to be created?
Also, how do I authenticate the user using Pusher?
According to this Stack Overflow link they are getting from Rails the CSRF value like this - csrf = $('meta[name=csrf-token]').attr('content'). But I could not implement the same in React.
Answer from the author of the git repo.
The example I created here was pretty bare bones but below are a few bullet points that I hope will explain how you could expand on it.
Add a User model and Thread model to the Rails app
When a User is created, generate a public UID for the user (you can use Ruby's built-in SecureRandom.uuid to generate the id) and save that to the DB. This would become the ID for that user that you would expose in your javascript to allow for communications between users. All users would have a UID.
When a Thread is Created, generated a thread UID this would become the unique id for the conversation taking place
Add a Users_Threads has_and_belongs_to_many relationship so that you can eventually track the users that are subscribed to which threads
When React app loads, use an Ajax request to get a list of the current User's friends (returns list of user details + their uid) and a request to get all threads for current User
So let's say for example a User named Fred clicked on a User named Bob and wanted to send Bob a message but they do not currently have a thread. Fred types the message, clicks Submit and you send an Ajax request containing the message text, from_uid (Fred) and to_uid (Bob) with thread_uid as null (since there is no existing convo and no existing thread).
Your Rails app then receives that requests at a controller and sees that Fred is trying to send Bob a message and the thread ID is null, so the controller create a new thread (with its own UID) and then add two entries to users_threads one for the new thread_uid and bob's uid and another for the new thread_uid and Fred's uid. After that, you'd create a Message with that thread_uid and the participant details.
You'd also probably want users to see that they are part of a new thread without having to reload the page so you'd I think you'd want a Pusher channel subscription just for notifying users of a new thread. So I'd say in the UserThreads model after create a new thread you could send something like Pusher.trigger('threads_channel', user_secret_uid, { thread: new_thread_uid }). You'd also need to make sure in the react app that each user subscribes to the threads_channel for their user_secret_uid. For security, i'd make sure this is a different uid than the messaging otherwise people could subscribe to a list of a different users threads.
My problem currently is that when a user wants to create an account on my app (using Firebase) the following error occurs:
2017-07-12 21:57:05.958 GeneralMessage[8525] [Firebase/Database][I-RDB038012] Listener at /users failed: permission_denied
I realise that the error occurs because the user attempts to read from the database without being signed in to an account (authenticated). The problem also being that the user will NEVER be authenticated at the time they are testing if a name is taken (before they make the account).
I know that you can edit the Realtime Database rules to allow unauthenticated users to access the database but I also read that this was a security hazard and should only be used during testing.
My idea was to temporarily authenticate the user when they click the 'Create Account' button but I am also unsure about how I would do this.
Thank you for any help :)
If you want unauthenticated users to be able to read part of your database, you'll need to modify your security rules to allow that. There is no way to do this temporarily for a specific app instance, since that would require each app instance to be identified - like a user.
I know two approaches:
Sign the user in with anonymous authentication first
Store the user names in an unprotected part of the tree
Sign the user in with anonymous authentication first
Alternatively you can initially sign the user in with anonymous authentication:
Auth.auth().signInAnonymously() { (user, error) in
// ...
}
This only partially secures data access: since the user doesn't prove their identity, it's relatively easy for anyone to still get access to the data. That's why I recommend limiting the data they can access by...
Store the user names in an unprotected part of the tree
This approach is quite common: you want the usernames to be publicly readable, so you store that in a separate part of your database.
usernames
"T. Dess": 8295647
"Frank van Puffelen": 209103
And then with your security rules:
{
"rules": {
"users": {
".read": "auth !== null",
"$uid": {
".write": "auth.uid === $uid"
}
},
"usernames": {
".read": true
}
}
}
So with these rules:
Anyone can read the usernames
Any authenticated user can read the user profiles
Each signed in user can only modify their own user profile
I'm trying to think of the best way to structure a database to allow users to send/accept/decline users as friends.
I've currently got a system that allows users to search through users, checks all the necessary stuff like people already being on their list bhalbhla, but I don't know how to finish it off with actually sending the invites.
My structure looks like:
Users
290384239843
friends:
093824098209384: true
username: Bob
Usernames
Bob: 290384239843
I figure when I hit the add button, it sends something to both users on Firebase, and I think the two options are:
users
29038493
friends
0283940839024: pending
or
users
02938409384
friends
3094809384903 : true
pendingFriends:
0283940839024: true
I think both could potentially work, but I figured I'd reach out incase I could get some guidance from someone with more experience with this. Maybe there's a better way entirely different?
Both your options look good to me.
You have to think about where you want this information regarding "friend requests" to be displayed in your app and if you need it displayed in other ways (like see all pending friend requests or see all the friend requests a user has sent out) and duplicate the request data to all the nodes you need.
You can also use, instead of status = "pending" a simple true \ false value.
True = friends
False = not approved
Null = does not exist
I am writing an application and need to read basic Instagram user info such as username, #posts, #followers and etc. This works well for public users but for private users returns:
{
"meta":
{
"code":400,
"error_message":"you cannot view this resource",
"error_type":"APINotAllowedError"
}
}
Let's say I am signed in as user A, and we want to show information from User B which is private to user A (user B also authorized my application to access it's basic info). I am using the following end point to read user B information:
https://api.instagram.com/v1/users/<userB_ID>/?access_token=<myAccessToken>
Am I missing something? or should I use different end point?
Update (Solution #1)
It seems one solution to fix this is to use Query end point. I was trying to manage all my work with Instagram user IDs (not usernames) but it seems I have to use usernames for the query. Is there a way to use query with user ID?
Here is what it looks like:
https://api.instagram.com/v1/users/search?q=<UserB_Username>&client_id=<myClientID>
if <myAccessToken> is to get user A's info, you can't get User B's info with it. If you have a backend to this app, then you can store different access tokens for each user, and make the call with the appropriate access token, and feed the info to the app through your own API.