how to store image upload based on user id - ios

func uploadImage(){
let storage = Storage.storage()
let storageRef = storage.reference()
let uploadData = self.imageView.image!.jpegData(compressionQuality: 0.75)
let imagesRef = storageRef.child("images/myImage.jpg") //not sure how is it done
let uploadTask = imagesRef.putData(uploadData!, metadata: nil) { (metadata, error) in
guard let metadata = metadata else {
return
}
let size = metadata.size
imagesRef.downloadURL { (url, error) in
guard let downloadURL = url else {
return
}
}
}
}
func retrieveData(){
let userID = Auth.auth().currentUser?.uid
ref.child("users").child(userID!).observeSingleEvent(of: .value, with: { (snapshot) in
let userData = snapshot.value as? NSDictionary
print("Welcome back,", userData?["username"])
}) { (error) in
print(error.localizedDescription)
}
}
Hi, I'm looking for a way for user to upload image onto firebase based on their user id. Can anyone suggest how this can be achieved? Thanks in advance.

You can do something like this:
func sendMessageWithProperties(properties: [String: Any]) {
let ref = Database.database().reference().child("messages")
let childRef = ref.childByAutoId()
let toId = self.user?.id
let fromId = Auth.auth().currentUser?.uid
let timestamp: Int = Int(NSDate().timeIntervalSince1970)
var values: [String: Any] = ["toId": toId!,
"fromId": fromId!,
"timestamp": timestamp]
// To append other properties into values
properties.forEach({values[$0] = $1})
childRef.updateChildValues(values) { (error, ref) in
if error != nil {
print(error!)
return
}
let userMessageRef = Database.database().reference().child("user-messages").child(fromId!).child(toId!)
let messageId = childRef.key
userMessageRef.updateChildValues([messageId: 1])
let receiverMessageRef = Database.database().reference().child("user-messages").child(toId!).child(fromId!)
receiverMessageRef.updateChildValues([messageId: 1])
}
}

Related

Why does it overwritten data instead of adding more data in firebase?

I really want to know why the data is overwritten when the user types new data,
I want it to add more data to it not overwrite it the data
Also want to know how to read it
Thank you in advance
let oDB = Database.database().reference().child("Data")
let oDictionary = ["Data1" : strange.text! , "Data2" : stranger.text!]
let uid = Auth.auth().currentUser?.uid
oDB.child(uid!).setValue(oDictionary) {
(error, reference) in
if error != nil{
print(error!)
} else {
print("saved Sucessfully")
self.navigationController?.popViewController(animated: true)
}
}
//In another ViewController
func updateRequest() {
let uid = Auth.auth().currentUser?.uid
let yDb = Database.database().reference().child("Data").child(uid!)
postDb.observeSingleEvent(of: .value) { (snapShot) in
if let snapShotValue = snapShot.value as? Dictionary<String, String> {
let text = snapShotValue["Data1"]!
let case = snapShotValue["Data2"]!
let data = Data()
data.s= text
data.y = case
self.array.append(data)
self.table.reloadData()
}
}
}
setValue overwrites the old content , You may need childByAutoId
oDB.child(uid!).childByAutoId().setValue(oDictionary) {
(error, reference) in
if error != nil{
print(error!)
} else {
print("saved Sucessfully")
self.navigationController?.popViewController(animated: true)
}
This will give this structure
Data
> uid
> someKey1 <<<< auto generated
Data1:"---"
Data2:"---"
> someKey2 <<<< auto generated
Data1:"---"
Data2:"---"
Read
//In another ViewController
func updateRequest() {
let uid = Auth.auth().currentUser?.uid
let yDb = Database.database().reference().child("Data").child(uid!)
postDb.observeSingleEvent(of: .value) { (snapShot) in
if let snapShotValue = snapShot.value as? [String:[String:String]] {
Array(snapShotValue.values).forEach {
let data = Data()
data.s= $0["Data1"]!
data.y = $0["Data2"]!
self.array.append(data)
}
self.table.reloadData()
}
}
}

retrieve chat message in firebase issue in ios swift

I am using firebase for chat app.when I try to send a message. than message, table got value but not update chat-message table. I refer to this link Here [https://github.com/DevSurya/ChatApp-Swift-And-Firebase].
when I run demo its working fine. Observe method is not calling in my case and collectionview is not refreshing
This is how I write data :
private func sendMessageWithProperty(_ property: [String: AnyObject]){
let ref = Database.database().reference().child("messages")
let childRef = ref.childByAutoId()
let toId = user!.id!
let fromId = Auth.auth().currentUser!.uid
let timeStamp = NSNumber.init(value: Date().timeIntervalSince1970)
var values: [String : AnyObject] = ["toId":toId as AnyObject, "fromId":fromId as AnyObject, "timeStamp":timeStamp]
values = values.merged(with: property)
childRef.updateChildValues(values)
childRef.updateChildValues(values) { (error, ref) in
if error != nil {
print(error!)
return
}
self.inputTextField.text = nil
let userMessageRef = Database.database().reference().child("user-messages").child(fromId).child(toId)
let messageId = childRef.key
userMessageRef.updateChildValues([messageId: 1])
let recipentUserMessageRef = Database.database().reference().child("user-messages").child(toId).child(fromId)
recipentUserMessageRef.updateChildValues([messageId: 1])
}
}
This is how I read data
func observeMessage() {
guard let uid = Auth.auth().currentUser?.uid, let toId = user?.id else {
return
}
let userMessageRef = Database.database().reference().child("user-messages").child(uid).child(toId)
userMessageRef.observe(.childAdded, with: { (snapshot) in
let messageId = snapshot.key
let messagesRef = Database.database().reference().child("messages").child(messageId)
messagesRef.observeSingleEvent(of: .value, with: { (snapshot) in
guard let dict = snapshot.value as? [String: AnyObject] else {
return
}
let message = Message()
message.setValuesForKeys(dict)
self.messages.append(message)
DispatchQueue.main.async {
self.collectionView?.reloadData()
let indexpath = NSIndexPath.init(item: self.messages.count-1, section: 0)
self.collectionView?.scrollToItem(at: indexpath as IndexPath, at: .bottom, animated: true)
}
}, withCancel: nil)
}, withCancel: nil)
}
The ObserveMessage() function get automatically called when there is an update in database.but in my case its not get called. I think the problem is with user-messages table: it is not created when I send message.

How can i fix the error on the DispatchGroup leave in swift

I want to load all data from firebase, then show the data to the table view. But now, I can't show all the data to the table view. It is because call the finishLoading(realm) method is faster than the for loop get all the data. How can I do some show all data when for loop is finish in swift. I have to use the Closure, however the second of the loop is later than this "self.finishLoading(realm: realm)"
I have to try to add the DispatchGroup(), however, the leave() when having an error of EXC_BAD_INSTRUCTION. Can I put the leave() in the closure? How can I fix it?
func loopAllProduct(userId: String, finishLoadWhenErr:Bool, storedClosure: #escaping (DocumentSnapshot) -> Void){
let storage = Storage.storage()
let db = Firestore.firestore()
let userDocRef = db.collection("Users").document(userId).collection("Product")
userDocRef.getDocuments{(document, error) in
if let err = error {
print("Error getting documents: \(err)")
} else {
for document in document!.documents {
storedClosure(document)
}
}
}
}
func downloadData() {
let startTime = Date()
while updating {
let diffTime = Date(timeIntervalSinceReferenceDate: startTime.timeIntervalSinceReferenceDate)
if (diffTime.timeIntervalSinceNow < -5){
self.stopAnimating()
self.refreshControl?.endRefreshing()
print("Update Timeout")
return
}
}
updating = true
let storage = Storage.storage()
let db = Firestore.firestore()
let productLoading = NSMutableArray()
let realm = try! Realm()
print("all posts")
let group = DispatchGroup()
let addPosts: (DocumentSnapshot)->Void = {(document) in
try! realm.write {
if let resuls = self.realmResults {
realm.delete(resuls);
}
}
let product = Product()
product.id = document.documentID
product.userID = document.data()?["UserID"] as? String
product.userName = document.data()?["UserName"] as? String
product.descrition = document.data()?["Descrition"] as? String
product.postTime = document.data()?["PostTime"] as? Date
product.price = document.data()?["Price"] as? Double ?? 0.0
product.stat = (document.data()?["stat"] as? Int)!
product.productName = document.data()?["ProductName"] as? String
let productId = document.documentID
productLoading.add(productId)
try! realm.write {
realm.add(product)
}
group.leave()
}
let userDocRef = db.collection("Users")
userDocRef.getDocuments{(document, error) in
for document in document!.documents {
group.enter()
self.loopAllProduct(userId:document.documentID , finishLoadWhenErr: true, storedClosure: addPosts)
}
}
group.notify(queue: DispatchQueue.main) {
self.finishLoading(realm: realm)
}
}

Display uploaded image using the new Firebase. swift 4

How can I download the image I uploaded in Firebase?
Here is how I upload my images:
func uploadProfileImage(_ image:UIImage, completion: #escaping ((_ url:URL?)->())) {
guard let uid = Auth.auth().currentUser?.uid else { return }
let storage = Storage.storage()
let storageRef = storage.reference().child("user/\(uid)")
guard let imageData = UIImageJPEGRepresentation(image, 0.75) else { return }
let metaData = StorageMetadata()
metaData.contentType = "image/jpg"
storageRef.putData(imageData, metadata: metaData) { metaData, error in
if let error = error {
print(error.localizedDescription)
return
}
storageRef.downloadURL(completion: { (url, error) in
if let _ = error{
return
}
if url != nil{
completion(url)
}
})
}
}
func saveProfile(username:String, profileImageURL:URL, completion: #escaping ((_ success:Bool)->())) {
guard let uid = Auth.auth().currentUser?.uid else { return }
let databaseRef = Database.database().reference().child("users/profile/\(uid)")
let userObject = [
"username": username,
"photoURL": profileImageURL.absoluteString ] as [String:Any]
databaseRef.setValue(userObject) { error, ref in
completion(error == nil)
}
}
But I'm not sure how I could download and display it. Any pointers?
Thank you in advance.

Convert JSON to dictionary in swift 3 for uplaod image from facebook to firebase

I want to upload my profile picture from facebook to firebase and then want to retrieve...
my code was working well in swift 2.0 i-e
let urlPic = (data?.objectForKey("url"))! as! String
when I convert it to swift 3.0 i-e
let urlPic = ((data as AnyObject).object("url"))! as! String
There is an error
Cannot call Value of non-function type 'Any?!'
There is my complete code please help...
if let user = FIRAuth.auth()?.currentUser {
// User is signed in.
let name = user.displayName
let photoUrl = user.photoURL
let uid = user.uid
self.username.text = name
let data = try? Data(contentsOf: photoUrl!)
self.profilepic.image = UIImage(data: data!)
//------Saving in DB-----
let storage = FIRStorage.storage()
let storageRef = storage.reference(forURL: "my storage_url..")
let profilePicRef = storageRef.child(user.uid+"/userPic.jpg")
profilePicRef.data(withMaxSize: 1 * 1024 * 1024) { (data, error) -> Void in
if (error != nil) {
print("Unable to download the image")
} else {
if (data != nil)
{
self.profilepic.image = UIImage(data:data!)
}
}
}
if (profilepic.image == nil)
{ var profilepic = FBSDKGraphRequest(graphPath: "/me/picture", parameters: ["height":300 ,"width":300, "redirect": false], httpMethod: "GET")
profilepic?.start(completionHandler: {(connection, result, error) -> Void in
if error == nil {
let dictionary = result as? NSDictionary
let data = dictionary?.object(forKey: "data")
let urlPic = ((data as AnyObject).object("url"))! as! String
if let imageData = NSData(contentsOfURL: NSURL(string:urlPic)!) {
let profilePicRef = storageRef.child(user.uid+"/userPic.jpg")
let uploadTask = profilePicRef.putData(imageData, metadata:nil){
metadata, error in
if( error == nil){
let downloadUrl = metadata!.downloadURL
}
else { print("Error in downloading image") }
}
self.profilepic.image = UIImage(data: imageData)
}
}
})
}
} else {
// No user is signed in.
}
Thanks in advance!
In Swift use native Dictionary instead of NSDictionary and instead of object(forKey:) use subscript with Dictionary, so instead of casting result to NSDictionary cast it to [String:Any].
if error == nil {
if let dictionary = result as? [String:Any],
let dataDic = dictionary["data"] as? [String:Any],
let urlPic = dataDic["url"] as? String {
//access urlPic here
}
}
Note: In swift 3 use native Data and URL instead of NSData and NSURL.

Resources