Is there a way to track user Id between conversations without requiring the user to connect their Google account? Like an anon userId. I don't see any id field in the docs: https://dialogflow.com/docs/fulfillment#request
According to the latest usage, conv.user.id is DEPRECATED: Use conv.user.storage to store data instead
For more details, have a look at this answer by Prisoner.
you can get userId like this:
let userId = conv.user.id;
Sample intent:
app.intent(INTENT_DEFAULT_WELCOME, conv => {
let id = conv.user.id;
conv.ask(`Welcome ${id}`);
})
Related
I need to send or create the list of user emails to our business facebook account as an audience list ,so that we can use it for our marketing purposes(I'm using Python 3.8).
Below is the code which i got from Google, But when i searched i found that we cannot directly pass the emails to Facebook via API.
Do you have any suggestions on how to achieve it ?
Also "can i pass email ID's to this list "fields = [] in the below code ?
AND what does the "ID" means ?
from facebook_business.adobjects.adaccount import AdAccount
from facebook_business.adobjects.customaudience import CustomAudience
from facebook_business.api import FacebookAdsApi
access_token = 'EAAi0wZCiZxxxxxxxxxxxxxxxDZD'
app_secret = 'xxxxxxxxxxxxxxx'
app_id = 'xxxxxxxxxxx'
id = '<ID>'
fields = []
FacebookAdsApi.init(access_token=access_token)
print("Access succesful")
params = {
'name': 'My new Custom Audience',
'subtype': 'CUSTOM',
'description': 'People who purchased on my website',
'customer_file_source': 'USER_PROVIDED_ONLY',
}
print (AdAccount(id).create_custom_audience(
fields=fields,
params=params,
))
You should first create the Custom Audience like you already do, then you can add/remove emails with the SDK API (you do not need manually hash the email: the SDK will do it for you). As example:
custom_audience = CustomAudience(DocsDataStore.get('ca_id'))
response = custom_audience.add_users(
schema=CustomAudience.Schema.email_hash,
users=[
'joe#example.com',
]
)
If you take a look of the SDK DOC Here:
CustomAudience.add_users (schema, users, is_raw, app_ids, pre_hashed)
pre_hashed: Whether or not the data has already been hashed. If not, the SDK will automatically hash the data
See also the SDK Doc TestCase here
I'm trying to use the Google Authentication provider and then use the information for an authenticated user in a Database Rule to restrict access to data. For example, say I sign in with my Google id me#gmail.com.
Something kind of like the following (taken from the firestore docs):
let provider = new firebase.auth.GoogleAuthProvider();
let result = await firebase.auth().signInWithPopup(provider);
let token = result.credential.accessToken;
let user = result.user;
// ...
In the above user.email would be me#gmail.com at this point.
Now how do I use that info in a rule to allow writing to the data. I thought it would be something like:
match /events/{events} {
allow write: if request.auth.uid = // Something?
}
but I cannot figure out how to know what to compare to uid. Ideally it would be the email address (i.e. something human-readable).
My goal here is that I as the administrator keep a list of authorized users, and then they can come log into my app and access the data.
Like Doug Stevenson wrote in the comments you have to use request.auth.token.email. If you want to compare the email in your security rules, you also have to store the email address of the user in your firestore db so you can compare like this:
match /events/{events} {
allow write: if request.auth.token.email == resource.data.email;
}
or you do it with the uid like this:
match /events/{events} {
allow write: if request.auth.uid = resource.data.uid;
}
Of course you have to store the uid in your firestore db, too.
So, say user registration is done (this code is already correct) and the next window asks users to enter personal info (education etc), how do you code that this information goes to Firebase under the user's profile.
I have the registration page done and users created there already go to firebase.
This is what I have for the page after registration. No errors but obviously incomplete.
The below code is what I found, but it is only for entering data in to database. It doesn't work on 2 points:
it it not dynamic data entered by user, it is simply the description of what the user is asked,
it doesn't go under the user's profile in firebase.
func post() {
let MainFunInterest = "MainFunInterest"
let SomethingInterestingIhaveRead = "SomethingInterestingIhaveRead"
let JobOrEducation = "JobOrEducation"
let WhatIamConsideringBuying = "WhatIamConsideringBuying"
let post : [String : AnyObject] = ["MainFunInterest" : MainFunInterest as AnyObject,
"SomethingInterestingIhaveRead" : SomethingInterestingIhaveRead as AnyObject,
"JobOrEducation" : JobOrEducation as AnyObject,
"WhatIamConsideringBuying" : WhatIamConsideringBuying as AnyObject]
let databaseRef = Database.database().reference()
databaseRef.child("personal info").childByAutoId().setValue(post)
}
I need the user's entry to go under his profile in firebase.
You can add a ‘users’ node through .child() and then set their personal information by their personal UID from .getUID
So the database could look like this:
Users -
(Their personal UID) -
Name - ‘Terry’
Email - ‘terry#email.com’
Phone - ‘0978364727’
When you call databaseRef.childByAutoId() Firebase generates a new child node under databaseRef. So if you call that multiple times, you get multiple new child nodes, even when the calls are for the same user.
To store data for users, you'll want to (as Nathan answered) store that data under that user's unique UID. That way you can update it later if needed, and easily find the data for a user without having to query for it.
To store the data under the user's UID, do something like this:
let uid = Auth.auth().currentUser.uid
databaseRef.child("personal info").child(uid).setValue(post)
For more on this, see:
the Firebase documentation on basic write operations.
the Firebase documentation on getting the currently signed in user.
Adding data to a specific UID in firebase
How to save to Firebase - Swift
so I already finished all of the actual app for this. I just need to setup the backend. I figured Firebase was the best solution since Parse is no longer a thing. What I wanted was:
Users with profiles - These profiles can be viewed by added friends but only edited (written) to by the actual profile owner.
So I read through the Firebase Docs and still cannot really figure out how to do this. They only have 1 Swift application example that does not do anything similar and the one Obj C twitter one, will not even build. All of their docs still have println for Swift which just makes me think it is not updated frequently.
Does anyone have any good examples / tutorials of this? I keep trying to search for things but nothing is as similar enough to what I want. I am more looking on how to setup the db for each user and access it rather actually using Firebase in Swift.
As I wrote in my comment to your question, this answer is based on what we do in a real social app Impether using Swift + Firebase.
Data structure
Let's assume that you want to store the following information for a single user:
email
username
name
followers - number of people who follow a particular user
following - number of people who a particular user follows
avatar_url - url of their avatar
bio - some additional text
Since in Firebase everything is stored a JSON objects, you can store the above structure under node with path like users/$userId, where $userId is Firebase User UID which is created for each registered user if you use simple email/password Firebase authorization.
Firebase email/password authorization is described in their docs:
https://www.firebase.com/docs/ios/guide/user-auth.html
https://www.firebase.com/docs/ios/guide/login/password.html
Notice that there are both Obj-C and Swift snippets. I find Firebase documentation really great as it helped me a lot when I was building our app.
For the purpose of this answer let's assume that we have user with username jack and Firebase User UID equal to jack_uid (in reality this will be a string generated by Firebase).
Then an example data for this user will be store under a path users/jack_uid and can look like this:
{
"email" : "jack#example.com",
"username" : "jack",
"name" : "Jack",
"followers" : 8,
"following" : 11,
"avatar_url" : "http://yourstoragesystem.com/avatars/jack.jpg",
"bio" : "Blogger, YouTuber",
}
Firebase email/password authorization works really well, but let's be honest, if user wants to sign in into the app, it's a lot better for him to use his username than his email he gave while he registering his account.
In order to do that, we decided to store a mapping from usernames to user ids. The idea is that if user inputs his username and password in a login form, we use that mapping to retrieve his user id and then we try to sign him in using his user id and provided password.
The mapping can be stored for example under a path username_to_uid and looks like this:
{
"sample_username_1": "firebase_generated_userid_1",
"sample_username_2": "firebase_generated_userid_2",
...
"jack": "jack_uid",
"sample_username_123": "firebase_generated_userid_123"
}
Then creating a profile may looks like this and it's done as soon as registration of a new account was successful (this snippet is very close to the exact code we use in the production):
func createProfile(uid: String, email: String,
username: String, avatarUrl: String,
successBlock: () -> Void, errorBlock: () -> Void) {
//path to user data node
let userDataPath = "/users/\(uid)"
//path to user's username to uid mapping
let usernameToUidDataPath = "/username_to_uid/\(username)"
//you want to have JSON object representing user data
//and we do use our User Swift structures to do that
//but you can just create a raw JSON object here.
//name, avatarUrl, bio, followers and following are
//initialized with default values
let user = User(uid: uid, username: username, name: "",
avatarUrl: avatarUrl, bio: "",
followers: 0, following: 0)
//this produces a JSON object from User instance
var userData = user.serialize()
//we add email to JSON data, because we don't store
//it directly in our objects
userData["email"] = email
//we use fanoutObject to update both user data
//and username to uid mapping at the same time
//this is very convinient, because either both
//write are successful or in case of any error,
//nothing is written, so you avoid inconsistencies
//in you database. You can read more about that technique
//here: https://www.firebase.com/blog/2015-10-07-how-to-keep-your-data-consistent.html
var fanoutObject = [String:AnyObject]()
fanoutObject[userDataPath] = userData
fanoutObject[usernameToUidDataPath] = uid
let ref = Firebase(url: "https://YOUR-FIREBASE-URL.firebaseio.com/images")
ref.updateChildValues(fanoutObject, withCompletionBlock: {
err, snap in
if err == nil {
//call success call back if there were no errors
successBlock()
} else {
//handle error here
errorBlock()
}
})
}
In addition to this you possibly want to store for each user a list of his followers and a separate list of users he follows. This can be done just by storing user ids at a path like followers/jack_uid, for example it can look like this:
{
"firebase_generated_userid_4": true,
"firebase_generated_userid_14": true
}
This is the way we store sets of values in our app. It very convenient, because it is really user to update it and check if some value is there.
In order to count the number of followers, we put this counter into user's data directly. This makes reading the counter very efficient. However, updating this counter requires using transactional writes and the idea is almost exactly the same as in my answer here: Upvote/Downvote system within Swift via Firebase
Read/write permissions
A part of your question is how to handle permissions to data you store. The good news is that Firebase is exceptionally good here. If you go to your Firebase dashboard there is a tab named Security&Rules and this is the place where you control permissions to your data.
What's great about Firebase rules is that they are declarative, which makes them very easy to use and maintain. However, writing rules in pure JSON is not the best idea since it's quite hard to control them when you want to combine some atomic rules into a bigger rule or your app simple grows and there are more and more different data you store in your Firebase database. Fortunately, Firebase team wrote Bolt, which is a language in which you can write all rules you need very easily.
First of all I recommend to read Firebase docs about Security, especially how does permission to a node influences permission for its children. Then, you can take a look at Bolt here:
https://www.firebase.com/docs/security/bolt/guide.html
https://www.firebase.com/blog/2015-11-09-introducing-the-bolt-compiler.html
https://github.com/firebase/bolt/blob/master/docs/guide.md
For example, we use rules for managing users data similar to this:
//global helpers
isCurrentUser(userId) {
auth != null && auth.uid == userId;
}
isLogged() {
auth != null;
}
//custom types, you can extend them
//if you want to
type UserId extends String;
type Username extends String;
type AvatarUrl extends String;
type Email extends String;
type User {
avatar_url: AvatarUrl,
bio: String,
email: Email,
followers: Number,
following: Number,
name: String,
username: Username,
}
//user data rules
path /users/{$userId} is User {
write() { isCurrentUser($userId) }
read() { isLogged() }
}
//user's followers rules
//rules for users a particular
//user follows are similar
path /followers/{$userId} {
read() { isLogged() }
}
path /followers/{$userId}/{$followerId} is Boolean {
create() { isCurrentUser($followerId) && this == true }
delete() { isCurrentUser($followerId) }
}
//username to uid rules
path /username_to_uid {
read() { true }
}
path /username_to_uid/{$username} is UserId {
create() { isCurrentUser(this) }
}
The bottom line is that you write rules you want using Bolt, then you compile them into JSON using Bolt compiler and then you deploy them into your Firebase, using command line tools or by pasting them into dashboard, but command line is way more efficient. A nice additional feature is that you can test your rules by using tools in Simulator tab in your dashboard.
Summary
For me Firebase is a great tool for implementing a system you want. However, I recommend to start with simple features and learn how to use Firebase in the first place. Implementing social app with functionality like for example Instagram is quite a big challenge, especially if you want to do it right :) It's very tempting to put all functionality there very quickly and Firebase makes it relatively easy to do, but I recommend to be patient here.
In addition, take your time and invest in writing tools. For example, we have two separated Firebase databases, one for production and second for testing, which is really important if you want to write unit and UI tests efficiently.
Also, I recommend building permission rules from the beginning. Adding them later may be tempting, but also quite overwhelming.
Last but not least, follow Firebase blog. They post regularly and you can be up to date with their latest features and updates - this is how I learnt how to use concurrent writes using fanout technique.
In the context of a given Facebook app, suppose User A invited user B to start using it. Once User B accepts to use the app, is there any way to retrieve the ID of User A programmatically (via either PHP/JS SDK) ? This doesn't seem quite documented.
For what it's worth, A/B users are friends, if it's any use.
when user comes following the app request, you can get request id's using
$_GET['request_ids']
then retrieve all the request ids with which you can call graph api to get the corresponding request details like below:
if(isset($_GET['request_ids']))
{
$request_ids = $_GET['request_ids'];
}
$request_ids = explode(",", $request_ids);
foreach($request_ids as $request_id)
{
$request_object = $facebook->api($request_id);
//this $request_object have sender facebook id in the field uid_from
}
If you look here:
http://developers.facebook.com/docs/reference/dialogs/requests/
You can see the object layout. Of note is the data property:
Optional, additional data you may pass for tracking. This will be
stored as part of the request objects created. The maximum length is
255 characters.
In this object you can add your referring UserId and then when the request is claimed, you can then process it on your end.
Hope this helps.