Ошибка значения: один или несколько компонентов не являются строкой или являются пустыми при попытке обновить документ Firestore со словарем в облачных функциях

#python #google-cloud-firestore #google-cloud-functions

# #python #google-cloud-firestore #google-cloud-функции

Вопрос:

Я пытаюсь создать облачную функцию Google с помощью моего скрипта Python, но я продолжаю получать сообщение об ошибке. Я получаю сообщение об ошибке при попытке обновить поле в документе firestore с помощью вложенного словаря. Вот мой фрагмент кода, где это происходит:

 driverDB = driverDB = db.collection('drivers')
driverList = []
for doc in driverDB.get():
    driverList.append(doc.id)

for driver in range(0,len(driverList)):
    routeDataDict = {
       'route':routeByDriverDict[driver]
    }
   
    driverDB.document(driverList[driver]).update(routeDataDict)
 

Ошибка, которую я получаю,:

 File "/layers/google.python.pip/pip/lib/python3.8/site-packages/google/cloud/firestore_v1/field_path.py", 
line 272, in __init__ raise ValueError(error) ValueError: One or more components is not a string or is empty.
 

routeDataDict выглядит следующим образом:

 {'route': {'stop_1': {'name': 'Christa',
   'address': '742 Evergreen Terrace',
   'phone': 5555555555,
   'email': 'test@test.com',
   'has_reusables': False,
   'notes': None,
   'zone': 1,
   'leg_url': '',
   'seconds_until_arrival': 360.0,
   'completed': False,
   'num_containers_at_this_stop': 0},
  'url': 'https://www.google.com/maps/dir/39.74,15.0757',
  'pay': '$49.77',
  'partner': 'burger_hut',
  'date': datetime.datetime(2020, 11, 24, 1, 7, 1, 90282)}}
 

И driverList [driver] корректно выводит строку идентификатора документа, поэтому ошибка, похоже, находится в словаре.

Полный стек ошибок:

 Traceback (most recent call last): File "/layers/google.python.pip/pip/lib/python3.8/site-packages/flask/app.py", line 2447, in wsgi_app response = self.full_dispatch_request() File "/layers/google.python.pip/pip/lib/python3.8/site-packages/flask/app.py", 
line 1952, in full_dispatch_request rv = self.handle_user_exception(e) File "/layers/google.python.pip/pip/lib/python3.8/site-packages/flask/app.py", 
line 1821, in handle_user_exception reraise(exc_type, exc_value, tb) File "/layers/google.python.pip/pip/lib/python3.8/site-packages/flask/_compat.py", 
line 39, in reraise raise value File "/layers/google.python.pip/pip/lib/python3.8/site-packages/flask/app.py", line 1950, in full_dispatch_request rv = self.dispatch_request() File "/layers/google.python.pip/pip/lib/python3.8/site-packages/flask/app.py", 
line 1936, in dispatch_request return self.view_functions[rule.endpoint](**req.view_args) File "/layers/google.python.functions-framework/functions-framework/lib/python3.8/site-packages/functions_framework/__init__.py", line 66, in view_func return function(request._get_current_object()) File "/workspace/main.py", 
line 282, in routeCreatorMain driverDB.document('Lu2qHfOqtma48r7L2g4PsEDQizD2').update({'route':routeByDriverDict[driver]}) File "/layers/google.python.pip/pip/lib/python3.8/site-packages/google/cloud/firestore_v1/document.py", 
line 284, in update batch, kwargs = self._prep_update(field_updates, option, retry, timeout) File "/layers/google.python.pip/pip/lib/python3.8/site-packages/google/cloud/firestore_v1/base_document.py", 
line 232, in _prep_update batch.update(self, field_updates, option=option) File "/layers/google.python.pip/pip/lib/python3.8/site-packages/google/cloud/firestore_v1/base_batch.py", 
line 126, in update write_pbs = _helpers.pbs_for_update( File "/layers/google.python.pip/pip/lib/python3.8/site-packages/google/cloud/firestore_v1/_helpers.py", 
line 847, in pbs_for_update extractor = DocumentExtractorForUpdate(field_updates) File "/layers/google.python.pip/pip/lib/python3.8/site-packages/google/cloud/firestore_v1/_helpers.py",
 line 798, in __init__ super(DocumentExtractorForUpdate, self).__init__(document_data) File "/layers/google.python.pip/pip/lib/python3.8/site-packages/google/cloud/firestore_v1/_helpers.py", 
line 422, in __init__ for field_path, value in iterator: File "/layers/google.python.pip/pip/lib/python3.8/site-packages/google/cloud/firestore_v1/_helpers.py", 
line 369, in extract_fields for s_path, s_value in extract_fields(value, field_path): File "/layers/google.python.pip/pip/lib/python3.8/site-packages/google/cloud/firestore_v1/_helpers.py", 
line 369, in extract_fields for s_path, s_value in extract_fields(value, field_path): File "/layers/google.python.pip/pip/lib/python3.8/site-packages/google/cloud/firestore_v1/_helpers.py", 
line 364, in extract_fields sub_key = FieldPath(key) File "/layers/google.python.pip/pip/lib/python3.8/site-packages/google/cloud/firestore_v1/field_path.py",
 line 272, in __init__ raise ValueError(error) ValueError: One or more components is not a string or is empty.
 

Когда я запускаю свой код в записной книжке jupyter, все работает нормально. Когда я запускаю его в облачных функциях, я получаю указанную выше ошибку. Когда я копирую внутренности словаря и жестко кодирую его в команду обновления в облачных функциях, это работает. Но когда я печатаю словарь в журнале облачных функций, а затем копирую и вставляю его в функцию обновления, он НЕ работает. Похоже, что-то происходит с облачной функцией, которая портит словарь.

Это данные в firestore (в настоящее время это старый маршрут) введите описание изображения здесь

Комментарии:

1. Какое именно значение driverList[driver] непосредственно перед ошибкой?

2. Привет @DougStevenson это строка, которая является именем идентификатора документа. Это UID пользователя. Я проверил это, передав простой словарь команде update, и обновление работает и обновляет документ в firestore. Похоже, проблема с вложенным словарем.

3. Итак, когда вы регистрируете его, каково его точное значение?

4. Когда я регистрирую UID, это некоторая символьная строка типа «Lu2qHfOqtma48r7L2g4PsEDQizD2», и она относится к классу str. Словарь выглядит так, как указано выше. Интересно, что когда я копирую и вставляю этот словарь из своего ноутбука jupyter в облачные функции, он работает. Но когда я печатаю словарь в своих журналах функций Google Cloud, а затем копирую и вставляю его, чтобы жестко закодировать его в облачной функции, он не работает. Что-то происходит в облачных функциях Google, из-за чего они не могут правильно обработать словарь. И весь мой код отлично работал при запуске его в записной книжке jupyter

5. не могли бы вы поделиться структурой данных, как в firestore. Это stop1 карта?

Ответ №1:

Вы уверены, что doc.id это не целое число?
Если это целое число, попробуйте выполнить приведение в string ( doc.id.toString() ), потому что firestore принимает ключ только как string или null

Комментарии:

1. Да, он включает в себя символы. Это строка аутентификации UID firebase. Я также протестировал его, передав простой тестовый словарь, и он обновляется должным образом

Ответ №2:

вы не можете хранить ключи в виде целых чисел в firestore. Это похоже на JSON. Попробуйте сделать json.loads(json.dumps(your_dict)) это, чтобы преобразовать ваши целочисленные ключи dict в строку. Теперь вы можете записать это в firebase.