如何通过Firebase REST API获取新ChildByAutoID且不写入实际数据
刚好我之前研究过这个问题,给你一步步讲清楚怎么用Firebase REST API实现和SDK一样的自动ID生成+图片上传流程~
实现步骤:用Firebase REST API生成自动ID并上传图片
1. 生成Firebase风格的自动ID
Firebase SDK里childByAutoId()生成的是基于时间戳+随机数的唯一ID,用REST API的话,我们可以借助Realtime Database的POST请求来生成这个ID——不需要真的留存数据,只是借它生成ID而已:
具体做法:
向你的Realtime Database的一个临时路径(比如temp_ids)发送POST请求,随便传个占位JSON数据,Firebase会自动返回生成的ID在name字段里。之后你可以选择删除这个临时数据,保持数据库整洁。
给你一段Swift的实现代码:
import Foundation func generateFirebaseAutoId(completion: @escaping (String?, Error?) -> Void) { // 替换成你的Realtime Database URL guard let dbURL = URL(string: "https://<你的数据库ID>.firebaseio.com/temp_ids.json") else { completion(nil, NSError(domain: "无效URL", code: -1, userInfo: nil)) return } var request = URLRequest(url: dbURL) request.httpMethod = "POST" // 传个占位数据,只是为了触发ID生成 request.httpBody = "{\"dummy\": true}".data(using: .utf8) request.setValue("application/json", forHTTPHeaderField: "Content-Type") let task = URLSession.shared.dataTask(with: request) { data, response, error in if let error = error { completion(nil, error) return } guard let data = data else { completion(nil, NSError(domain: "无返回数据", code: -2, userInfo: nil)) return } do { if let json = try JSONSerialization.jsonObject(with: data) as? [String: Any], let autoId = json["name"] as? String { // 可选操作:删除刚才生成的临时数据 let deleteURL = URL(string: "\(dbURL.absoluteString)/\(autoId)")! var deleteRequest = URLRequest(url: deleteURL) deleteRequest.httpMethod = "DELETE" URLSession.shared.dataTask(with: deleteRequest).resume() completion(autoId, nil) } else { completion(nil, NSError(domain: "解析ID失败", code: -3, userInfo: nil)) } } catch { completion(nil, error) } } task.resume() }
2. 用生成的ID上传图片到Firebase Storage
拿到自动ID后,就可以把它作为文件名,通过Storage的REST API上传图片。这里需要注意:上传请求需要携带Firebase的ID Token来授权(可以通过Auth REST API获取,比如匿名登录或邮箱密码登录)。
Swift实现代码:
func uploadImageToStorage(with autoId: String, imageData: Data, idToken: String, completion: @escaping (Error?) -> Void) { // 替换成你的Storage Bucket名称 let bucketName = "<你的Bucket名>.appspot.com" // 自定义图片存储路径+生成的ID作为文件名 let fileName = "user_images/\(autoId).jpg" guard let encodedFileName = fileName.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed), let uploadURL = URL(string: "https://firebasestorage.googleapis.com/v0/b/\(bucketName)/o?name=\(encodedFileName)") else { completion(NSError(domain: "无效上传URL", code: -1, userInfo: nil)) return } var request = URLRequest(url: uploadURL) request.httpMethod = "PUT" request.httpBody = imageData // 带上Auth令牌授权 request.setValue("Bearer \(idToken)", forHTTPHeaderField: "Authorization") request.setValue("\(imageData.count)", forHTTPHeaderField: "Content-Length") // 根据图片类型设置Content-Type,比如png就改成image/png request.setValue("image/jpeg", forHTTPHeaderField: "Content-Type") let task = URLSession.shared.dataTask(with: request) { data, response, error in if let error = error { completion(error) return } // 检查HTTP响应状态码,200-299表示上传成功 if let httpResponse = response as? HTTPURLResponse, !(200...299).contains(httpResponse.statusCode) { let error = NSError(domain: "上传失败", code: httpResponse.statusCode, userInfo: ["message": "状态码错误"]) completion(error) return } completion(nil) } task.resume() }
3. 关键配置注意事项
- Realtime Database规则:确保你的临时路径允许写入,比如可以在规则里加:
{ "rules": { "temp_ids": { ".write": "request.auth != null", // 或者根据你的需求设置,比如允许匿名写入 ".read": false } } } - Storage规则:确保上传路径有写入权限,比如:
rules_version = '2'; service firebase.storage { match /b/{bucket}/o { match /user_images/{allPaths=**} { allow write: if request.auth != null; } } } - 获取ID Token:如果是匿名用户,可以通过POST请求到
https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=<你的API密钥>,请求体传{"returnSecureToken": true},返回结果里的idToken就是需要的授权令牌。
内容的提问来源于stack exchange,提问作者Alk
相关产品推荐
相关产品推荐

